我做了一个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服务器不能。
有谁知道发生了什么事?
提前致谢,
麦克
答案 0 :(得分:1)
因为socket.io的正常使用不希望常规的http中间件看到socket.io连接请求(它们通常会触发404响应),所以socket.io将其自己的请求处理程序放在第一行之前,即使是那些在安装之前就已存在。
你可以在这里看到它是如何做到的:{。3}}在engine.io源代码中。
我可以想到以下几种方法可以在socket.io看到之前预处理请求:
handleRequest()
方法,这是在有传入连接请求时调用的方法。您可以看到其代码https://github.com/socketio/engine.io/blob/master/lib/server.js#L437。