Javascript websockets-检测具有相同ID和;"踢",;他们
这是我的服务器端websocket脚本:Javascript websockets-检测具有相同ID和;"踢",;他们,javascript,websocket,Javascript,Websocket,这是我的服务器端websocket脚本: var clients = [ ]; //sample request: ****:8080/?steamid=123456789 var connection; var aqsteamid = getParameterByName("steamid",request.resource); connection = request.accept(null, request.origin); connection.ID = aqsteamid; c
var clients = [ ];
//sample request: ****:8080/?steamid=123456789
var connection;
var aqsteamid = getParameterByName("steamid",request.resource);
connection = request.accept(null, request.origin);
connection.ID = aqsteamid;
connection.balRefreshes = 0;
connection.clientIndex = clients.push(connection) - 1;
//check if this user is already connected. If yes, kicks the previous client ***====EDITED====***
for(var i = 0; i < clients.length; i++)
{
if(clients[i].ID === aqsteamid){
var indx = clients.indexOf(clients[i]);
clients[indx].close();
}
}
console.log('ID',connection.ID,' connected.');
socket.on('close', function(webSocketConnection, closeReason, description){
try{
console.log('ID',webSocketConnection.ID,'disconnected. ('+closeReason+';'+description+')');
webSocketConnection.balRefreshes = 0;
webSocketConnection.spamcheck = false;
clients.splice(webSocketConnection.clientIndex, 1);
}catch(e)
{
console.log(e);
}
});
var客户机=[];
//样本请求:***:8080/?steamid=123456789
无功连接;
var aqstreamid=getParameterByName(“streamid”,request.resource);
连接=request.accept(null,request.origin);
connection.ID=aqsteamid;
connection.balRefreshes=0;
connection.clientIndex=客户端。推送(连接)-1;
//检查此用户是否已连接。如果是,踢上一个客户端***==已编辑====***
对于(变量i=0;i
基本上,我想要的是使用相同的ID(例如,使用多个浏览器选项卡连接)启动所有连接
但是,它不踢旧客户机,而是踢两个客户机,或者在某些情况下,两个客户机使用相同的ID保持连接
我的剧本中有没有其他方法或错误
谢谢听起来,具有相同ID的多个连接可能是具有多个选项卡的真正工作流的一部分(不像恶意用户故意通过多个线程刮取数据…) 与其将用户从其他选项卡“踢”出来,然后再重新连接,更优雅的解决方案是在多个选项卡上引入编排层 您可以依靠localstorage api来选择一个主选项卡,该选项卡将处理与服务器的通信(不管是websocket还是ajax),并通过localstorage与其他选项卡共享响应。当您可以共享数据时,是否打开了1个或20个选项卡并不重要,因为您关心的是相同的消息通知、股票行情更新或其他信息 发件人:
storage
事件允许您在选项卡之间传播数据,同时保持
单信号机连接打开(从而阻止连接
饱和)。调用localStorage.setItem('sharedKey',sharedData)
将在所有其他选项卡(不是调用者)中引发存储
事件:
根据上面的代码,如果加载页面时sharedKey
值已经可用,则假定主选项卡处于活动状态,并从localstorage获取共享值。您可以检查是否需要每隔一段时间重新选择主选项卡(即浏览器选项卡已关闭或导航离开),或者是否需要依赖更复杂的选项,如
注意:您不仅限于在多个选项卡上共享“相同”的数据,而是通过共享通道批处理任何请求。使用对象数组对
客户端
池进行键控,使其更快、更简单:
var clients = {};
//sample request: ****:8080/?steamid=123456789
var connection;
var aqsteamid = getParameterByName("steamid",request.resource);
connection = request.accept(null, request.origin);
connection.ID = aqsteamid;
connection.balRefreshes = 0;
clients[aqsteamid]=connection;
socket.on('close', function(webSocketConnection, closeReason, description){
try{
console.log('ID',webSocketConnection.ID,'disconnected. ('+closeReason+';'+description+')');
webSocketConnection.balRefreshes = 0;
webSocketConnection.spamcheck = false;
delete clients[aqsteamid];
}catch(e)
{
console.log(e);
}
});
//check if this user is already connected. If yes, kicks the previous client
if(clients[aqsteamid]) clients[aqsteamid].close();
console.log('ID',connection.ID,' connected.');
使用对象池,我们可以删除所有阵列池循环和比较逻辑,我们的索引将永远不会失去同步。
clients.splice(webSocketConnection.clientIndex,1)代码>是问题所在splice()
更改它前面元素的索引,因此您的clientIndex
属性与客户机
不匹配的时间很长,这就解释了所描述的不稳定症状。您可能需要先使用clients.indexOf()
来查找连接的当前索引,然后再使用splice()
作为旁白,最好使用具有ID键的对象,而不是在每个连接事件中通过数组循环<代码>已使用={};。。如果(used[aqstreamid]){…}或者{used[aqstreamid]=connection}
并且在断开连接时,删除比删除拼接更简单:删除used[webSocketConnection.ID]嘿,谢谢你的回复。我改变了一点循环,但它仍然是一样的。是否必须使用used=[]示例执行此操作?您只能做一件事,首先检查连接是否存在,然后检查连接是否存在,这样就没有机会创建具有相同连接的另一个客户端id@dandavis我忘了在“关闭”事件中更改脚本,现在似乎工作正常。谢谢,请写一个答案,这样我就可以接受了。
var clients = {};
//sample request: ****:8080/?steamid=123456789
var connection;
var aqsteamid = getParameterByName("steamid",request.resource);
connection = request.accept(null, request.origin);
connection.ID = aqsteamid;
connection.balRefreshes = 0;
clients[aqsteamid]=connection;
socket.on('close', function(webSocketConnection, closeReason, description){
try{
console.log('ID',webSocketConnection.ID,'disconnected. ('+closeReason+';'+description+')');
webSocketConnection.balRefreshes = 0;
webSocketConnection.spamcheck = false;
delete clients[aqsteamid];
}catch(e)
{
console.log(e);
}
});
//check if this user is already connected. If yes, kicks the previous client
if(clients[aqsteamid]) clients[aqsteamid].close();
console.log('ID',connection.ID,' connected.');