【发布时间】:2015-02-05 14:13:13
【问题描述】:
我正在使用 Express 和 Socket.IO 构建一个 NodeJS 应用程序,它指示客户端脚本根据特定条件将用户重定向到不同的页面。我遇到的问题是,当它重定向时,我得到了另一个套接字连接。在我的代码中,我根据套接字 ID 跟踪套接字会话,以便将消息发送到特定套接字以对其执行操作。由于重定向创建了一个具有新 ID 的新套接字,因此我不再能够实现此功能。
我尝试在重定向之前断开套接字,在连接后发送消息以断开前一个套接字等。似乎没有什么可以让我通过重定向轻松管理单个套接字连接。
免责声明:我对 Node、Socket.io 等完全陌生。
这是我的服务器代码:
var http = require('http'),
express = require('express');
var app = express();
var server = http.createServer(app);
var io = require('socket.io')(server);
var port = 8000;
app.use(express.static(__dirname + '/public'));
var activeClientId;
var clientQ = [];
var clients = {};
var numUsers = 0;
function updateActive() {
console.log("Updating active client...");
activeClientId = clientQ.shift();
var active = clients[activeClientId];
while (!checkActive() && clientQ.length > 0) {
if (typeof active !== 'undefined' && active !== null) {
delete clients[activeClientId];
active.disconnect();
console.log("Force Disconnect Client: " + activeClientId);
numUsers = Object.keys(clients).length;
}
activeClientId = clientQ.shift();
active = clients[activeClientId];
}
if (checkActive()) {
console.log("New Active Client: " + activeClientId);
} else {
console.log("Active Client Not Updated");
}
};
function checkActive() {
var active = clients[activeClientId];
return typeof active !== 'undefined' && active !== null && active.connected;
};
io.on('connection', function (socket) {
clients[socket.id] = socket;
clientQ.push(socket.id);
numUsers = Object.keys(clients).length;
console.log("Client " + "#" + numUsers + " connected: " + socket.id);
if (numUsers === 1) {
activeClientId = socket.id;
} else {
updateActive();
}
if (socket.id === activeClientId) {
socket.emit('game');
} else {
socket.emit('wait');
}
socket.on('play', function () {
console.log("users: " + numUsers);
console.log("curId: " + socket.id);
console.log("actId: " + activeClientId);
if (socket.id !== activeClientId && numUsers > 1) {
socket.emit('kick');
} else {
console.log("Game started on client: " + socket.id);
}
});
socket.on('disconnect', function () {
console.log("Client " + "#" + numUsers + " disconnected: " + socket.id);
delete clients[socket.id];
numUsers = Object.keys(clients).length;
updateActive();
socket.broadcast.emit('disconnected', {
numUsers: numUsers
});
});
});
server.listen(port, function () {
console.log('Listening on port: %d', port);
});
还有我的客户:
$(function () {
var socket = io();
socket.on('game', function (data) {
socket.disconnect();
window.location.replace("/game");
});
socket.on('wait', function (data) {
socket.disconnect();
window.location.replace("/wait");
});
});
/game 页面的代码:
$(function () {
var socket = io();
socket.on('connect', function (data) {
socket.emit('play');
});
socket.on('kick', function(data) {
socket.disconnect();
alert("KICK!");
window.location.replace("/wait");
});
});
\wait 页面的代码:
$(function () {
var socket = io();
socket.on('connect', function (data) {
socket.emit('wait');
});
socket.on('game', function (data) {
socket.disconnect();
window.location.replace("/game");
});
});
【问题讨论】:
-
每个新网页都将是一个新的套接字连接,因为您无法跨页面保留连接,因此如果您要重定向到新页面,您将丢失之前的套接字连接。您可以使用 id 对浏览器进行 cookie,当它在重定向后重新连接时,使用该 id。
-
是的,这是有道理的。但是当我重定向时,如果连接没有被保留,那不应该触发 socket.io 的
disconnect吗?目前不是,这导致我的连接会话数组在每次重定向时不断增长。 -
如果你正在监听正确的事件,服务器上应该有一个断开事件。
-
我在服务器上使用
socket.on('disconnect'),并在其回调中将消息记录到控制台。当我重定向到另一个页面时,我没有看到任何断开连接,只有当我手动关闭选项卡时。span> -
我确实在客户端中看到了问题,您在连接后立即尝试在套接字上
.emit()而无需等待连接事件(这意味着您无需等待 socket.io 执行这是最初的握手)。这可能会使事情变得复杂,因为您可能会在那里遇到错误,导致套接字立即关闭。
标签: javascript node.js sockets redirect socket.io