Socket.io在Express 4路由中添加侦听器

时间:2015-11-16 20:05:25

标签: node.js express socket.io

我在单独的模块中声明套接字服务器。我可以在应用程序的任何地方访问服务器的对象,例如我可以发出声明。但我无法在路线中添加听众,例如:

router.post('/example', function(req, res, next) {
  var socketio = req.app.get('sock');

  socketio.sockets.on('connection', function (socket) {
    socket.on('message', function (text) {
        console.log('ok');
    });
});

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:0)

如果只有一个设备要与之通信并且它应该已经连接到您的服务器而req.app.get('sock')是您访问socketio服务器对象的方式,那么您可以这样做它是这样的:

var theDeviceSocket;
req.app.get('sock').on('connection', function(socket) {
    theDeviceSocket = socket;
});

router.post('/example', function(req, res, next) {
    if (theDeviceSocket) {
        theDeviceSocket.emit("someMsg", "someData");
    }
    // send whatever response you want to send
    res.end();
});

如果你试图从单个设备获得响应并将其作为对POST的响应返回,那么你可以这样:

// store the one connection to/from the special device
var theDeviceSocket;

// keep a request cntr so we can tell which response goes with which request
var requestCntr = 0;

req.app.get('sock').on('connection', function(socket) {
    theDeviceSocket = socket;
});

router.post('/example', function(req, res, next) {
    var timer, thisRequestId;

    function gotData(data) {
        // if this is our specific response
        if (data.requestId === thisRequestId) {
            theDeviceSocket.removeListener("someMsgResponse", gotData);
            res.send(data);
            clearTimeout(timer);
        }
    }

    if (theDeviceSocket) {
        theDeviceSocket.on("someMsgResponse", gotData);
        thisRequestId = requestCntr++;
        theDeviceSocket.emit("someMsg", {requestId: thisRequestId});

        // set up a timeout in case we don't get the proper response
        timer = setTimeout(function() {
            theDeviceSocket.removeListener("someMsgResponse", gotData);
            res.send("error");
        }, 5000);
    }
});

第二种方案很复杂,因为您已将此架构设计为请求/响应方案,但socket.io不是请求/响应协议。因此,为了知道哪个响应属于哪个请求(当可能有多个客户端同时与服务器交互时),您必须在通过socket.io发送和接收的数据中实现某种requestId。这意味着您必须更改设备以回显您通过响应发送的requestId。如果您使用专为请求/响应设计的协议(如HTTP而不是socket.io),则所有这些都不是必需的。