Javascript websockets-检测具有相同ID和;"踢",;他们

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

这是我的服务器端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;
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]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.');