在快速路线内等待socketio事件 [英] Wait for socketio event inside express route

查看:151
本文介绍了在快速路线内等待socketio事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用express,socketio和socketio-client。
(我对nodejs堆栈不太满意......)

I'm using express,socketio and socketio-client in my application. (I not very comfortable with nodejs stack...)

总结我的应用程序流程:
Client => node / express API + Socketoi server< => nodejs(Socketio-client)

to summarize my application flow : Client => node/express API + Socketoi server <=> nodejs (Socketio-client)


  1. 浏览器向nodejs / express发送请求(route / api)

  2. 使用中间件覆盖一些请求标头

  3. 在路由'/'中,服务器将一个emit发送到nodejs(Socketio-client)

  4. 执行一些逻辑后,socketio-client发出一个带有逻辑结果的事件

  5. 我需要将此结果发送到客户端的响应中

  1. browser send request to a nodejs/express (route /api)
  2. Do some request headers overwrites with middlewares
  3. In the route '/', server sends an emit to a nodejs (Socketio-client)
  4. after executing some logic, socketio-client emit an event with the logics result
  5. I need this result to be send in the response to the client

我的代码如下:

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);
    });
  }
});

我的问题
这只是我第一次工作发送一个获取 http:// localhost:3000 / api 的浏览器。 __ res.body 在浏览器中打印。

My problem : This works only the first time I send a Get http://localhost:3000/api frome the browser. __res.body is printed in the browser.

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 .__ socket.on('respp',函数(数据){...}永远不会被服务器捕获。

Next request will just wait for server to respond, which is, I suspect, not happening because the app.io.__socket.on('respp', function (data){...} is never catched by the server.

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

After sending more request (while the others are waiting), I noticed this warning in server logs:

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

在向客户发送响应之前,是否还有其他方法可以捕获路由中的事件? / strong>

Is there other ways to catch events in a route before sending response to clients?

推荐答案

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

You could remove the event listener when the socket closes to avoid the event listener leak:

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 .__ socket 应该是 app.io.sockets 或者不是,但我从代码中复制它,假设你知道你在做什么。

I'm not sure if app.io.__socket should really be app.io.sockets or not, but I copied it as-is from your code, assuming you know what you're doing.

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

Additionally, you may wish to add some sort of timeout so as not to keep the request waiting indefinitely.

这篇关于在快速路线内等待socketio事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆