Nodejs请求代理流(mjpeg)连接永远不会结束
Nodejs request proxy stream(mjpeg) connection never ends
(不必要的背景故事)
我有一个带有 expressjs 框架的 nodejs 服务器,它代理流式传输网络摄像头源。我需要这个的原因是由于复杂的 CORS 问题,mjpg 流必须来自该服务器。
//proxy from webcam server to avoid CORS complaining
app.get('/stream1',function(req,res){
var url="http://camera.nton.lviv.ua/mjpg/video.mjpg"
request(url).pipe(res);
});
问题:
问题很简单。 request(url).pipe(res)
永远不会关闭,因为源是 mjpeg,它实际上永远不会结束。当客户端(浏览器;目标)不再可用时,我需要找到一种方法来强制关闭此管道 - 例如,关闭 window.
使用socket.io监听远程连接
// install it on your project
npm install socket.io
// require it on server side
var socket = require('socket.io');
// listen for sockets from your server
var mysocks = socket.listen(myexpressappvar);
// keep collection of sockets for use if needed
// its good practice
var connectedSockets = [];
// add event handelers on server side
mysocks.sockets.on("connection", function(socket){
// add socket to our collection
connectedSockets.push(socket);
// you will need to bind their stream id here.
exe.....
// listen for disconnected
socket.on("disconnect", function(){
// remove socket from collection
connections.splice(connections.indexOf(socket), 1);
// destory stream here
exe...
});
});
// last thing, is add socket.io to the client side.
<script src="/socket.io/socket.io.js"></script>
// then call connect from client side js file
var socket = io.connect();
我找到了一个更简单的方法。为客户端连接关闭添加一个事件侦听器,并在它发生时强制关闭管道。
app.get('/stream1',function(req,res){
var url="http://camera.nton.lviv.ua/mjpg/video.mjpg"
var pipe=request(url).pipe(res);
pipe.on('error', function(){
console.log('error handling is needed because pipe will break once pipe.end() is called')
}
//client quit normally
req.on('end', function(){
pipe.end();
}
//client quit unexpectedly
req.on('close', function(){
pipe.end();
}
});
其他答案对我不起作用。
这一行 var pipe=request(url).pipe(res);
returns 管道而不是请求对象。所以我需要打破排队。
需要请求对象才能中止。调用 .end() 也没有用,但是 .abort() 成功了。我花了几个小时才找到适合我的答案,所以我想我会分享。
app.get('/cam/frontdoor',function(req,res){
var request_options = {
auth: {
user: '',
pass: ''},
url: 'http:/xx.xx.xx.xx/mjpg/video.mjpg',
};
var req_pipe = request(request_options);
req_pipe.pipe(res);
req_pipe.on('error', function(e){
console.log(e)
});
//client quit normally
req.on('end', function(){
console.log('end');
req_pipe.abort();
});
//client quit unexpectedly
req.on('close', function(){
console.log('close');
req_pipe.abort()
})
})
(不必要的背景故事) 我有一个带有 expressjs 框架的 nodejs 服务器,它代理流式传输网络摄像头源。我需要这个的原因是由于复杂的 CORS 问题,mjpg 流必须来自该服务器。
//proxy from webcam server to avoid CORS complaining
app.get('/stream1',function(req,res){
var url="http://camera.nton.lviv.ua/mjpg/video.mjpg"
request(url).pipe(res);
});
问题:
问题很简单。 request(url).pipe(res)
永远不会关闭,因为源是 mjpeg,它实际上永远不会结束。当客户端(浏览器;目标)不再可用时,我需要找到一种方法来强制关闭此管道 - 例如,关闭 window.
使用socket.io监听远程连接
// install it on your project
npm install socket.io
// require it on server side
var socket = require('socket.io');
// listen for sockets from your server
var mysocks = socket.listen(myexpressappvar);
// keep collection of sockets for use if needed
// its good practice
var connectedSockets = [];
// add event handelers on server side
mysocks.sockets.on("connection", function(socket){
// add socket to our collection
connectedSockets.push(socket);
// you will need to bind their stream id here.
exe.....
// listen for disconnected
socket.on("disconnect", function(){
// remove socket from collection
connections.splice(connections.indexOf(socket), 1);
// destory stream here
exe...
});
});
// last thing, is add socket.io to the client side.
<script src="/socket.io/socket.io.js"></script>
// then call connect from client side js file
var socket = io.connect();
我找到了一个更简单的方法。为客户端连接关闭添加一个事件侦听器,并在它发生时强制关闭管道。
app.get('/stream1',function(req,res){
var url="http://camera.nton.lviv.ua/mjpg/video.mjpg"
var pipe=request(url).pipe(res);
pipe.on('error', function(){
console.log('error handling is needed because pipe will break once pipe.end() is called')
}
//client quit normally
req.on('end', function(){
pipe.end();
}
//client quit unexpectedly
req.on('close', function(){
pipe.end();
}
});
其他答案对我不起作用。 这一行 var pipe=request(url).pipe(res); returns 管道而不是请求对象。所以我需要打破排队。
需要请求对象才能中止。调用 .end() 也没有用,但是 .abort() 成功了。我花了几个小时才找到适合我的答案,所以我想我会分享。
app.get('/cam/frontdoor',function(req,res){
var request_options = {
auth: {
user: '',
pass: ''},
url: 'http:/xx.xx.xx.xx/mjpg/video.mjpg',
};
var req_pipe = request(request_options);
req_pipe.pipe(res);
req_pipe.on('error', function(e){
console.log(e)
});
//client quit normally
req.on('end', function(){
console.log('end');
req_pipe.abort();
});
//client quit unexpectedly
req.on('close', function(){
console.log('close');
req_pipe.abort()
})
})