从映像资源请求中检测socket.io客户端

时间:2013-06-20 18:09:22

标签: node.js express socket.io cors mjpeg

我正在编写一个基于socket.io的网络摄像头流媒体应用程序,当应用程序超时时应该发出'streamComplete'事件。问题是,图像资源请求似乎没有发送与普通AJAX请求相同的标头/ cookie。这似乎使socket.io无法使用套接字识别请求,以便稍后可以告诉客户端流已完成。

在服务器端,我有一个node.js代理,用于提供mjpeg(移动jpeg)图像。当客户在应用程序中选择一个订阅源时,DOM中img元素的'src'属性会更改为指向相机订阅源的路径。

我已经研究了支持HTML5 CORS的图像规范,该规范似乎试图解决这个问题,但据我所知,该功能并未在大多数浏览器中完全实现。如果是,我无法弄清楚如何在node.js端允许这些请求 - 每当我向图像添加crossorigin ='use-credentials'时,就会出现错误

  

“跨源资源共享拒绝跨域图像加载”   策略“。

显然我应该能够解决这个问题,因为我控制了服务器端,但是下面的节点头规则似乎并没有起作用,即使它们看起来非常放松:

res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, XMLHttpRequest, X-HTTP-Method-Override, Content-Type");
res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, OPTIONS');

我考虑过的一个选项是将socketID添加到图像请求并在req.io.sockets.sockets [req.body.socketID]上注册侦听器。虽然看起来有点hacky,但我确信可能会带来其他问题,比如竞争条件。这是我试图完成此任务的部分代码。

app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'blahblahblah'}));

// Allow all cross origin requests.
app.use(allowCrossOrigin);

app.get('/streams/:cam_id/:framerate', function(req, res,next) {
    var camId = req.params.cam_id
      , framerate = req.params.framerate
      , type = (framerate === 0) ? 'jpeg' : 'mjpeg'
      , reqString = 'http://blahblah.com/feeds/'
      , proxy;

    // Query database for stream info.
    var query = new drupalInterface.Query(camId);

    // When query comes back build the URL request string and create proxy.
    query.on('results:available', function(results) {
        var reqArr = [
              results.site_name
            , results.camera_name
            , type
            , framerate
        ];

        reqString = reqString + reqArr.join('/') + '?status_frame=true&random=' + Math.random();

        // Create new proxy for current client.
        req.proxy = new MjpegProxy(reqString);

        // Make request to telepresence server.
        req.proxy.proxyRequest(req, res, next);

        // Forward to express.io route for emitting stream event info to clients.
        req.io.route('initializeProxyStream');
    });
});

app.io.route('initializeProxyStream', function(req) {
    var socket = app.io.sockets.sockets[req.query.socketID];
    // If connecting directly to /stream don't try to listen for socket connection.
    if(req.io) {
        req.proxy.once('streamComplete', function() {
            socket.emit('streamComplete');
        });
    }
});

我不确定express.io是否需要我正在做的事情,但在这种背景下似乎有道理。

我是否在使用crossorigin属性的正确轨道上?是否有一些我缺少的中间件?

0 个答案:

没有答案