从客户端订阅 NodeJS 服务器上的长处理请求反馈
Subscribe to long-processing request feedback on NodeJS server from client
我创建了一个执行以下操作的 Node JS 服务器:
- 使用 multer 将媒体文件(视频和图像)上传到服务器
- 如果媒体是图像,则使用清晰度调整大小
- 如果媒体是视频,则使用 fluent-ffmpeg 调整大小并压缩它
- 将文件上传到 Firebase 存储进行备份
这一切都在流利地工作。问题是,当上传的文件很大时,请求处理需要很长时间。所以我想在客户端显示一些进展如下:
- 状态1.媒体正在上传-> n%
- 状态2.媒体在压缩
- 状态 3. 媒体正在上传到云端 -> n%
- 状态 4. 结果 -> JSON = {status: "ok", uri: .., cloudURI: .., ..}
Firebase 存储 API 在我们创建上传任务时具有如下所示的功能:
let uploadTask = imageRef.put(blob, { contentType: mime });
uploadTask.on('state_changed', (snapshot) => {
if (typeof snapshot.bytesTransferred == "number") {
let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
}
});
我发现,可以使用 websockets 实现这一点,如果有其他方法可以做到这一点,我很感兴趣。
还有一种方法Accessing partial response using AJAX or WebSockets?,但我正在寻找更灵活、更专业的解决方案。
我已经使用 GraphQL 订阅解决了这个问题。使用 WebSockets 可以实现相同的方法。解决该问题的步骤如下:
Post 文件上传服务器
生成操作唯一 ID 并将其作为响应发送给客户端
例如:response = {op: "A78HNDGS89NSNBDV7826HDJ"}
- 通过 opID 创建订阅
例如:subscription { uploadStatus(op: "A78HNDGS89NSNBDV7826HDJ") { status }}
- 每次状态更改时,都会向 GraphQL 端点发送请求,该端点将数据发布到 pubsub。要从 nodejs 服务器发送 GraphQL 请求,您可以使用 https://github.com/prisma-labs/graphql-request
例如:
const { request } = require('graphql-request');
const GQL_URL = "YOUR_GQL_ENDPOINT";
const query = `query {
notify ("Status text goes here")
}`
request(GQL_URL, query).then(data =>
console.log(data)
)
通知解析器函数将数据发布到 pubsub
context.pubsub.publish('uploadStatus', {
status: "Status text"
});
如果你有更复杂的架构,你可以使用 RabbitMQ、Kafka 等消息代理
如果有人知道其他解决方案,请告诉我们)
我创建了一个执行以下操作的 Node JS 服务器:
- 使用 multer 将媒体文件(视频和图像)上传到服务器
- 如果媒体是图像,则使用清晰度调整大小
- 如果媒体是视频,则使用 fluent-ffmpeg 调整大小并压缩它
- 将文件上传到 Firebase 存储进行备份
这一切都在流利地工作。问题是,当上传的文件很大时,请求处理需要很长时间。所以我想在客户端显示一些进展如下:
- 状态1.媒体正在上传-> n%
- 状态2.媒体在压缩
- 状态 3. 媒体正在上传到云端 -> n%
- 状态 4. 结果 -> JSON = {status: "ok", uri: .., cloudURI: .., ..}
Firebase 存储 API 在我们创建上传任务时具有如下所示的功能:
let uploadTask = imageRef.put(blob, { contentType: mime });
uploadTask.on('state_changed', (snapshot) => {
if (typeof snapshot.bytesTransferred == "number") {
let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
}
});
我发现,可以使用 websockets 实现这一点,如果有其他方法可以做到这一点,我很感兴趣。
还有一种方法Accessing partial response using AJAX or WebSockets?,但我正在寻找更灵活、更专业的解决方案。
我已经使用 GraphQL 订阅解决了这个问题。使用 WebSockets 可以实现相同的方法。解决该问题的步骤如下:
Post 文件上传服务器
生成操作唯一 ID 并将其作为响应发送给客户端
例如:response = {op: "A78HNDGS89NSNBDV7826HDJ"}
- 通过 opID 创建订阅
例如:subscription { uploadStatus(op: "A78HNDGS89NSNBDV7826HDJ") { status }}
- 每次状态更改时,都会向 GraphQL 端点发送请求,该端点将数据发布到 pubsub。要从 nodejs 服务器发送 GraphQL 请求,您可以使用 https://github.com/prisma-labs/graphql-request
例如:
const { request } = require('graphql-request');
const GQL_URL = "YOUR_GQL_ENDPOINT";
const query = `query {
notify ("Status text goes here")
}`
request(GQL_URL, query).then(data =>
console.log(data)
)
通知解析器函数将数据发布到 pubsub
context.pubsub.publish('uploadStatus', {
status: "Status text"
});
如果你有更复杂的架构,你可以使用 RabbitMQ、Kafka 等消息代理
如果有人知道其他解决方案,请告诉我们)