Socket.io 无论我做什么都会重新连接
Socket.io reconnection firing no matter what i do
使用 socket.io 1.4.5。
似乎无论我做什么,我都无法阻止 socket.io 在互联网连接中断时触发重新连接事件或销毁客户端套接字。
在客户端,我有:
重新连接延迟:99999999,
超时:99999999999,
重新连接:假,
然而,如果互联网断开连接,套接字将变为未定义(大约 20 秒后),并且当互联网重新打开时将触发重新连接事件。
我的最终目标是在服务器和客户端上使用完全相同的套接字(不管它们已经通信了多长时间),除非该套接字在服务器上明确断开连接。我不能随意重新连接套接字,因为我将数据存储在套接字上并在我的应用程序中广泛使用 socket.id 。如果套接字和套接字 ID 突然改变,应用程序就会中断。
我认为您必须在握手时传递一些唯一的变量并通过该变量保存数据。
socket.id
的重新生成是 socket.io 的正常行为。
在我的实践中,我正在向服务器发出初始请求以创建 slot
变量并将其保存在 slots
集合中 mongodb
并且在我通过定义 slots
创建连接之后=13=] 作为握手的变量。
或者让我们简化对您问题的回答并使用:https://www.npmjs.com/package/express-socket.io-session
还有一点"hack"使用命名空间逻辑:https://socket.io/docs/rooms-and-namespaces/#custom-namespaces
奖金:
这是快速解决方案:
客户端:
function genUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
};
var namespace = localStorage.getItem("namespace");
if(!namespace) {
namespace = genUUID();
localStorage.setItem("namespace", namespace);
}
var connect = function (ns) {
return io.connect(ns, {
query: 'ns='+ns // this is handshake variable `ns`
});
}
var socket = connect('/'+namespace);
后端:
const
url = require('url'),
sharedData = {};
io.sockets.on('connection', (socket) => {
const handshake = url.parse(socket.handshake.url, true);
const ns = handshake.query ? handshake.query.ns : 'default';
console.log('GOT CONNECTION TO NS: '+ns);
io.of(ns).on('connection', (socket) => {
if(!sharedData[ns]) sharedData[ns] = {};
// put socket code here
socket.on('some-event', (data) => {
sharedData[ns]['some-event'] = data.someData;
});
});
});
使用 socket.io 1.4.5。
似乎无论我做什么,我都无法阻止 socket.io 在互联网连接中断时触发重新连接事件或销毁客户端套接字。
在客户端,我有: 重新连接延迟:99999999, 超时:99999999999, 重新连接:假,
然而,如果互联网断开连接,套接字将变为未定义(大约 20 秒后),并且当互联网重新打开时将触发重新连接事件。
我的最终目标是在服务器和客户端上使用完全相同的套接字(不管它们已经通信了多长时间),除非该套接字在服务器上明确断开连接。我不能随意重新连接套接字,因为我将数据存储在套接字上并在我的应用程序中广泛使用 socket.id 。如果套接字和套接字 ID 突然改变,应用程序就会中断。
我认为您必须在握手时传递一些唯一的变量并通过该变量保存数据。
socket.id
的重新生成是 socket.io 的正常行为。
在我的实践中,我正在向服务器发出初始请求以创建 slot
变量并将其保存在 slots
集合中 mongodb
并且在我通过定义 slots
创建连接之后=13=] 作为握手的变量。
或者让我们简化对您问题的回答并使用:https://www.npmjs.com/package/express-socket.io-session
还有一点"hack"使用命名空间逻辑:https://socket.io/docs/rooms-and-namespaces/#custom-namespaces
奖金:
这是快速解决方案:
客户端:
function genUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
};
var namespace = localStorage.getItem("namespace");
if(!namespace) {
namespace = genUUID();
localStorage.setItem("namespace", namespace);
}
var connect = function (ns) {
return io.connect(ns, {
query: 'ns='+ns // this is handshake variable `ns`
});
}
var socket = connect('/'+namespace);
后端:
const
url = require('url'),
sharedData = {};
io.sockets.on('connection', (socket) => {
const handshake = url.parse(socket.handshake.url, true);
const ns = handshake.query ? handshake.query.ns : 'default';
console.log('GOT CONNECTION TO NS: '+ns);
io.of(ns).on('connection', (socket) => {
if(!sharedData[ns]) sharedData[ns] = {};
// put socket code here
socket.on('some-event', (data) => {
sharedData[ns]['some-event'] = data.someData;
});
});
});