multipart/x-mixed-replace - MJPG 视频流无法关闭

问题描述 投票:0回答:1

我正在使用 Node.js 和 React。 在 React 中,我有一个简单的组件,单击按钮时会显示在屏幕上。组成部分如下:

import React from 'react'

const Image = () => {
  return <img src="/api/mjpgStream/stream01"></img>;
}

Webpack 重定向我的请求(api=localhost:3456/mjpgStream/stream0)。 在节点中,我创建了一个快速服务器,当接收到 GET 时,它会连续发送带有 multipart/x-mixed-replace 的 JPEG 图像。下面是代码:

const cb: RequestHandler = (req, res) => {
  const url = req.url.toString().slice(1);
  res.writeHead(200, {
    "Content-Type": "multipart/x-mixed-replace;boundary='stream'",
    Connection: "keep-alive",
    Expires: "Fri, 27 May 1977 00:00:00 GMT",
    "Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
    Pragma: "no-cache",
  });
  let sub = PubSub.subscribe(url, function (msg: any, data: any) {
    res.write("--stream\r\n");
    res.write("Content-Type: image/jpeg\r\n");
    res.write("Content-Length: " + data.length + "\r\n");
    res.write("\r\n");
    res.write(data, "binary");
    res.write("\r\n");
  });

  req.on("close", () => {
    PubSub.unsubscribe(sub);
    res.end();
  });

  res.on("error", function (err) {
    console.error("Error in response:", err);
  });
};

router.get(/\/[a-z,0-9]*/, cb);

视频流通过PubSub发布到主题中,并正确显示在Image组件中。 问题是,当我单击按钮从网页关闭 Image 组件时,express 服务器端未捕获关闭事件,并且 mjpg 流继续存在。我不明白为什么。

javascript reactjs node.js express ffmpeg
1个回答
0
投票

看起来您正在使用

req.on("close", ...)
事件来处理客户端关闭连接。但是,并非在所有情况下都会触发此事件,特别是在连接突然关闭或通信过程中出现错误的情况下。

为了确保服务器检测到客户端断开连接,除了

req.on("end", ...)
之外,还可以使用
req.on("close", ...)
事件。当请求已完全接收并且没有更多数据可从客户端读取时,将发出“end”事件。您可以按如下方式修改您的代码:

const cb: RequestHandler = (req, res) => {
  const url = req.url.toString().slice(1);
  res.writeHead(200, {
    "Content-Type": "multipart/x-mixed-replace;boundary='stream'",
    Connection: "keep-alive",
    Expires: "Fri, 27 May 1977 00:00:00 GMT",
    "Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
    Pragma: "no-cache",
  });

  let sub = PubSub.subscribe(url, function (msg: any, data: any) {
    res.write("--stream\r\n");
    res.write("Content-Type: image/jpeg\r\n");
    res.write("Content-Length: " + data.length + "\r\n");
    res.write("\r\n");
    res.write(data, "binary");
    res.write("\r\n");
  });

  req.on("end", () => {
    PubSub.unsubscribe(sub);
    res.end();
  });

  req.on("close", () => {
    PubSub.unsubscribe(sub);
    res.end();
  });

  res.on("error", function (err) {
    console.error("Error in response:", err);
  });
};

router.get(/\/[a-z,0-9]*/, cb);

这样,无论客户端连接是正常关闭还是突然关闭,服务器都应该处理清理逻辑并停止发送 MJPEG 流。此外,您可能还想向

end
事件添加错误处理,以确保在出现错误时进行正确的清理。

© www.soinside.com 2019 - 2024. All rights reserved.