Javascript 在快速路线内等待socketio事件

Javascript 在快速路线内等待socketio事件,javascript,node.js,express,socket.io,Javascript,Node.js,Express,Socket.io,我正在应用程序中使用express、socketio和socketio客户端。 (我对nodejs堆栈不太满意…) 要总结我的应用程序流程,请执行以下操作: 客户端=>node/express API+Socketoi服务器节点JS(Socketio客户端) 浏览器向nodejs/express发送请求(路由/api) 是否使用中间件覆盖某些请求头 在路由“/”中,服务器向nodejs(Socketio客户端)发送一个emit 执行某些逻辑后,socketio客户端将发出一个带有逻辑结果的事件

我正在应用程序中使用express、socketio和socketio客户端。 (我对nodejs堆栈不太满意…)

要总结我的应用程序流程,请执行以下操作: 客户端=>node/express API+Socketoi服务器节点JS(Socketio客户端)

  • 浏览器向nodejs/express发送请求(路由/api)
  • 是否使用中间件覆盖某些请求头
  • 在路由“/”中,服务器向nodejs(Socketio客户端)发送一个emit
  • 执行某些逻辑后,socketio客户端将发出一个带有逻辑结果的事件
  • 我需要将此结果发送到客户端的响应中
  • 我的代码如下:

    router.get('/*', function (req, res) {
      //emit data for socketio-client to apply some logic
      app.io.sockets.emit('req', {
        reqheader : req.headers,
        requrl : req.protocol + "://" + req.headers.host + req.url,
        reqmethod : req.method
      });
      console.log("after emit");
      //I use callback to make response wait for socketio server to catch event from client
      waitforevent(req, res, function (__res) {
        console.log("callback" );
        res.end(__res.body);
        res.sendStatus(__res.statusCode);
        //res.end();
      });
      function waitforevent(req, res, callback) {
        console.log("waiting for event" );
        app.io.__socket.on('respp', function (data) {
            //console.log("no response yet \n" + JSON.parse(data) );
            __res = JSON.parse(data);
            console.log("event catched...");
            callback(__res);
        });
      }
    });
    
    我的问题: 这仅在我第一次从浏览器发送Get时有效\uu res.正文在浏览器中打印

    req 1
    after emit
    waiting for event
    event catched...
    callback
    Error: Can't set headers after they are sent.   
    **GET /api 200 73.841 ms - -**
    
    req 2
    after emit
    waiting for event
    
    下一个请求将只等待服务器响应,我怀疑这不会发生,因为app.io.\uuu socket.on('respp',function(data){…}从未被服务器捕获

    在发送更多请求后(其他请求正在等待),我注意到服务器日志中出现以下警告:

    (node) warning: possible EventEmitter memory leak detected. 11 respp listeners added. Use emitter.setMaxListeners() to increase limit.
    

    在向客户端发送响应之前,是否有其他方法捕获路由中的事件?

    您可以在套接字关闭时删除事件侦听器,以避免事件侦听器泄漏:

    router.get('/*', function (req, res) {
      app.io.sockets.emit('req', {
        reqheader : req.headers,
        requrl : req.protocol + "://" + req.headers.host + req.url,
        reqmethod : req.method
      });
    
      req.socket.on('close', function() {
        app.io.__socket.removeListener('respp', resppHandler);
      });
      app.io.__socket.on('respp', resppHandler);
    
      function resppHandler(data) {
        data = JSON.parse(data);
        res.statusCode = data.statusCode;
        res.end(data.body);
      }
    });
    
    我不确定
    app.io.\uu socket
    是否真的应该是
    app.io.sockets
    ,但我从您的代码中复制了它,假设您知道自己在做什么


    此外,您可能希望添加某种超时,以避免请求无限期地等待。

    我用
    一次解决了

    var app = require('express')();
    var server = require('http').Server(app);
    var io = require('socket.io')(server);
    
    var socket;
    io.on('connection', function (sock) {
        console.log('Connected');
        socket = sock;
    });
    
    server.listen(3000);
    
    app.get('/*', function (req, res) {
        socket.once('event', function (data) {
            if (data.error) {
                console.log('is an error');
                res.status(400).json(data);
            } else {
                console.log('is ok');
                res.status(200).json(data);
            }
        });
        io.emit('ask-for-event', { data: data });
    });
    

    你能告诉我完整的代码吗?下面的答案不起作用anymore@mscdex我也遇到了同样的问题。上面的代码不起作用。你能帮我解决这个问题吗:尽管基本上没有解释,但用“once”替换“on”确实解决了我的问题。我不确定为什么事件会被多次发射或捕获,但是似乎是这样,至少对我来说是这样。