明顯的建議是停止讓客戶端連接兩次。
但是,如果你想防止服務器上的多個連接,你真的不希望任何最終用戶能夠同時使用多個窗口到您的網站,那麼你就可以防止其他連接一旦已經有連接。
的關鍵將是確定與某種獨特的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