websockets - 检测具有相同ID的多个客户端并“踢”它们
websockets - detect multiple clients with same ID and "kick" them
这是我的服务器端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);
}
});
基本上我想要的是踢所有具有相同ID的连接(例如,使用多个浏览器选项卡连接)。
但是,它不是踢旧客户端,而是踢两个客户端,或者在某些情况下,两个客户端都保持相同的 ID 连接。
还有其他方法还是我的脚本中有任何错误?
谢谢
使用 Array 的对象 instad 来键控clients
池可以更快、更简单:
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.');
使用对象池,我们可以删除所有数组池循环和比较逻辑,并且我们的索引永远不会不同步。
听起来具有相同ID的多个连接可能是具有多个选项卡的真正工作流程的一部分(不像恶意用户故意抓取具有多个线程的数据......
与其将用户从其他选项卡中"踢出",然后不得不处理他们重新连接,更优雅的解决方案是跨多个选项卡引入业务流程层。
您可以依靠 localstorage api 来选择一个主选项卡,该选项卡将处理与服务器的通信(无论是 websocket 还是 ajax 并不重要)并与其他选项卡共享响应 - 同样,通过 localstorage。当您可以共享该数据时,打开 1 个或 20 个选项卡并不重要,因为您关心相同的消息通知或股票行情更新或其他什么。
来自另一个堆栈溢出答案:
storage
事件允许您在选项卡之间传播数据,同时保持 单个 SignalR 连接打开(从而阻止连接 饱和度)。呼叫localStorage.setItem('sharedKey', sharedData)
将在所有其他选项卡(不是调用方)中引发storage
事件:$(window).bind('storage', function (e) { var sharedData = localStorage.getItem('sharedKey'); if (sharedData !== null) console.log( 'A tab called localStorage.setItem("sharedData",'+sharedData+')' ); });
给定上面的代码,如果在加载页面时sharedKey
值已经可用,则假设主选项卡处于活动状态并从本地存储获取共享值。您可以检查是否需要重新选择主选项卡(即浏览器选项卡已被关闭或导航离开),并具有间隔或依赖于更复杂的内容,例如页面可见性 api。
请注意,您不仅限于在多个选项卡之间共享"相同"数据,而是通过共享通道对任何请求进行批处理。
- 客户端服务器REST API captcha实现
- 使用谷歌应用程序脚本将服务器端数据表返回到客户端
- 如何使用Socket.io将命令从客户端发送到服务器
- 如何轻松地将服务器端变量从Java代码转移到客户端代码
- Meteor方法在客户端返回null,在客户端运行的相同方法返回正确的值
- 从客户端获取修改后的对象,并将其与服务器上的原始对象组合
- 如何将我的javascript库公开给其他客户端使用
- 是否可以使用JavaScript/AAJAX在客户端创建一个文件
- 如何使用Javascript客户端对象模型检索Sharepoint 2010列表项权限
- 返回/从Twit's客户端.get
- 将客户端特定的日期格式返回到服务器MVC4
- MobileFirst:在客户端运行计时器作业-最佳选项
- 标签客户端的设置值
- websockets - 检测具有相同ID的多个客户端并“踢”它们
- 主干 - 渲染客户端视图,然后在保存时创建它们
- 以下是客户端javascript的Models类的一些示例,它们具有层次结构文档而不是平面行
- 我可以保存图像或从客户端加载图像,而不是每次发送它们
- 如果HTML、CSS和Javascript是客户端,为什么它们是PHP文件的组成部分
- 在服务器、客户端和所有文件之间共享Meteor功能,而不声明它们为全局文件
- 从Angular客户端发送文件和附加参数,并在服务器端处理它们的最佳方式