明显的建议是停止让客户端连接两次。
但是,如果你想防止服务器上的多个连接,你真的不希望任何最终用户能够同时使用多个窗口到您的网站,那么你就可以防止其他连接一旦已经有连接。
的关键将是确定与某种独特的cookie(用户ID或唯一地生成的ID号)的各个浏览器。然后,您可以实施socket.io身份验证,以跟踪哪些用户ID已经拥有连接,并且如果连接已经处于活动状态,那么随后的连接尝试将失败身份验证步骤并断开连接。
认为你必须为每一个被称为userId
浏览器设置Cookie。那么,这里是一个示例应用程序,使确保userid cookie的存在,然后用它来否定一个以上socket.io连接:
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
const cookie = require('cookie');
app.use(cookieParser());
let userIdCntr = 1;
const tenDays = 1000 * 3600 * 24 * 10;
app.use(function(req, res, next) {
// make sure there's always a userId cookie
if (!req.cookies || !req.cookies.userId) {
// coin unique user ID which consists of increasing counter and current time
let userId = userIdCntr++ + "_" + Date.now();
console.log("coining userId: " + userId);
res.cookie('userId', userId, { maxAge: Date.now() + tenDays , httpOnly: true });
}
next();
});
app.get('/test.html', function (req, res) {
console.log('Cookies: ', req.cookies)
res.sendFile(__dirname + "/" + "test.html");
});
const server = app.listen(80);
const io = require('socket.io')(server);
// which users are currently connected
var users = new Set();
// make sure cookie is parsed
io.use(function(socket, next) {
if (!socket.handshake.headers.cookieParsed) {
socket.handshake.headers.cookieParsed = cookie.parse(socket.handshake.headers.cookie || "");
}
next();
});
// now do auth to fail duplicate connections
io.use(function(socket, next) {
console.log("io.use() - auth");
// if no userId present, fail the auth
let userId = socket.handshake.headers.cookieParsed.userId;
if (!userId) {
next(new Error('Authentication error - no userId'));
return;
}
// if already logged in
if (users.has(userId)) {
console.log("Failing user " + userId);
next(new Error('Authentication error - duplicate connection for this userId'));
return;
} else {
console.log("adding user " + userId);
users.add(userId);
}
next();
});
io.on('connection', function(socket) {
console.log("socket.io connection cookies: ", socket.handshake.headers.cookieParsed);
socket.on('disconnect', function() {
console.log("socket.io disconnect");
let userId = socket.handshake.headers.cookieParsed.userId;
users.delete(userId);
});
// test message just to see if we're connected
socket.on("buttonSend", function(data) {
console.log("buttonSend: ", data);
});
});
附:你必须仔细考虑一下,如果用户拥有多台计算机(比如家庭/办公室),将一台计算机留在网页上并打开你的页面,并通过socket.io连接,然后尝试从另一台计算机上使用你的网站。如果您拒绝第二次连接,如果第一台计算机发生打开和打开,这将拒绝他们从第二台计算机访问。
因此该解决方案来创建一个工厂,会在IO单身..如果我没看错 – Rastafari