为什么Socket.io服务器覆盖节点http中间件?

时间:2018-06-08 09:29:57

标签: node.js socket.io

我做了一个React应用程序,它在初始HTTP升级后完全依赖于WebSockets。出于安全考虑,我在WebSockets连接中使用cookie和JWT令牌。

一切正常,但是当打开一个新选项卡时,socket.io cookie会重新发布,我希望用户能够通过多个选项卡保持登录状态。所以我想设置一个cookie,如果客户端还没有。如果已有,则使用该cookie。

所以我想在Node的http服务器中处理第一个HTTP轮询请求并为其创建中间件:

// HTTP SERVER
const server = require('http').createServer(function (request, response) {
  console.log('test');
  console.log(request);

  if(!request.headers.cookie) { // cookie pseudo-logic
    response.writeHead(200, {
    'Set-Cookie': 'mycookie=test',
    'Content-Type': 'text/plain'
  });
}

// Socket.IO server instance
const io = require('socket.io')(server, {
  origins: config.allowedOrigins,
  cookie: false, // disable default io cookie
});

server.listen(port, () => console.log(`Listening on port ${port}`));

我使用Socket.io作为WebSockets框架。然而问题是,在注册Socket.io服务器时,这个中间件被忽略了。当我注释掉Socket.io服务器时,中间件处于活动状态并且请求被记录。

看起来Socket.io的服务器正在覆盖节点http服务器的处理程序。但是在Socket.io文档中,他们提供了这个例子:

var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');

app.listen(80);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

因此表明应该可以处理第一个http轮询请求以及套接字请求。我设法让它与Express一起工作,但我不明白为什么node的http服务器不能。

有谁知道发生了什么事?

提前致谢,

麦克

1 个答案:

答案 0 :(得分:1)

因为socket.io的正常使用不希望常规的http中间件看到socket.io连接请求(它们通常会触发404响应),所以socket.io将其自己的请求处理程序放在第一行之前,即使是那些在安装之前就已存在。

你可以在这里看到它是如何做到的:{。3}}在engine.io源代码中。

我可以想到以下几种方法可以在socket.io看到之前预处理请求:

  1. 在socket.io甚至看到请求之前,使用代理并在代理中执行cookie。
  2. 修补socket.io/engine.io代码,为你想要做的事情添加一个回调钩子。
  3. 在socket.io配置完成后,复制socket.io/engine.io使用的技术,使您自己的请求处理程序排在第一位。
  4. 找到一种方法来覆盖socket.io服务器对象的handleRequest()方法,这是在有传入连接请求时调用的方法。您可以看到其代码https://github.com/socketio/engine.io/blob/master/lib/server.js#L437