webSocketServer node.js 如何区分客户端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13364243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:37:59  来源:igfitidea点击:

webSocketServer node.js how to differentiate clients

node.jswebsocket

提问by Ajouve

I am trying to use sockets with node.js, I succeded but I don't know how to differentiate clients in my code. The part concerning sockets is this:

我正在尝试在 node.js 中使用套接字,我成功了,但我不知道如何在我的代码中区分客户端。关于套接字的部分是这样的:

var WebSocketServer = require('ws').Server, 
    wss = new WebSocketServer({port: 8080});
wss.on('connection', function(ws) {
    ws.on('message', function(message) {
        console.log('received: %s', message); 
        ws.send(message);
    });
    ws.send('something');
});

This code works fine with my client js.

此代码适用于我的客户端 js。

But I would like to send a message to a particular user or all users having sockets open on my server.

但我想向特定用户或所有在我的服务器上打开套接字的用户发送消息。

In my case I send a message as a client and I receive a response but the others user show nothing.

在我的情况下,我作为客户端发送消息并收到响应,但其他用户什么也没显示。

I would like for example user1 sends a message to the server via webSocket and I send a notification to user2 who has his socket open.

例如,我希望 user1 通过 webSocket 向服务器发送一条消息,然后向打开套接字的 user2 发送通知。

采纳答案by Ankit Bisht

You can simply assign users ID to an array CLIENTS[], this will contain all users. You can directly send message to all users as given below:

您可以简单地将用户 ID 分配给数组 CLIENTS[],这将包含所有用户。您可以直接向所有用户发送消息,如下所示:

var WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({port: 8080}),
    CLIENTS=[];

wss.on('connection', function(ws) {
    CLIENTS.push(ws);
    ws.on('message', function(message) {
        console.log('received: %s', message);
        sendAll(message);
    });
    ws.send("NEW USER JOINED");
});

function sendAll (message) {
    for (var i=0; i<CLIENTS.length; i++) {
        CLIENTS[i].send("Message: " + message);
    }
}

回答by Jzapata

In nodejs you can directly modify the ws client and add custom attributes for each client separately. Also you have a global variable wss.clientsand can be used anywhere. Please try the next code and try to connect at leat two clients:

在nodejs中可以直接修改ws客户端,分别为每个客户端添加自定义属性。您还有一个全局变量wss.clients并且可以在任何地方使用。请尝试下一个代码并尝试连接至少两个客户端:

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({
    server: httpsServer
});


wss.getUniqueID = function () {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
    }
    return s4() + s4() + '-' + s4();
};

wss.on('connection', function connection(ws, req) {
    ws.id = wss.getUniqueID();

    wss.clients.forEach(function each(client) {
        console.log('Client.ID: ' + client.id);
    });
});

You can also pass parameters directly in the client connection URL:

您也可以直接在客户端连接 URL 中传递参数:

https://myhost:8080?myCustomParam=1111&myCustomID=2222

https://myhost:8080?myCustomParam=1111&myCustomID=2222

In the connection function you can get these parameters and to assign these parameters directly to your ws client:

在连接函数中,您可以获取这些参数并将这些参数直接分配给您的 ws 客户端:

wss.on('connection', function connection(ws, req) {

    const parameters = url.parse(req.url, true);

    ws.uid = wss.getUniqueID();
    ws.chatRoom = {uid: parameters.query.myCustomID};
    ws.hereMyCustomParameter = parameters.query.myCustomParam;
}

回答by H Dog

This code snippetin Worlize server really helped me a lot. Even though you're using ws, the code should be easily adaptable. I've selected the important parts here:

Worlize 服务器中的这段代码片段对我帮助很大。即使您使用的是 ws,代码也应该很容易适应。我在这里选择了重要的部分:

// initialization
var connections = {};
var connectionIDCounter = 0;

// when handling a new connection
connection.id = connectionIDCounter ++;
connections[connection.id] = connection;
// in your case you would rewrite these 2 lines as
ws.id = connectionIDCounter ++;
connections[ws.id] = ws;

// when a connection is closed
delete connections[connection.id];
// in your case you would rewrite this line as
delete connections[ws.id];

Now you can easily create a broadcast() and sendToConnectionId() function as shown in the linked code.

现在您可以轻松地创建一个 broadcast() 和 sendToConnectionId() 函数,如链接代码所示。

Hope that helps.

希望有帮助。

回答by droid-zilla

It depends which websocket you are using. For example, the fastest one, found here: https://github.com/websockets/wsis able to do a broadcast via this method:

这取决于您使用的是哪个 websocket。例如,最快的,在这里找到:https: //github.com/websockets/ws能够通过这种方法进行广播:

var WebSocketServer = require('ws').Server,
   wss = new WebSocketServer({host:'xxxx',port:xxxx}),
   users = [];
wss.broadcast = function broadcast(data) {
wss.clients.forEach(function each(client) {
  client.send(data);
 });
};

Then later in your code you can use wss.broadcast(message) to send to all. For sending a PM to an individual user I do the following:

然后在您的代码中,您可以使用 wss.broadcast(message) 发送给所有人。为了向个人用户发送 PM,我执行以下操作:

(1) In my message that I send to the server I include a username (2) Then, in onMessage I save the websocket in the array with that username, then retrieve it by username later:

(1) 在我发送到服务器的消息中,我包含一个用户名 (2) 然后,在 onMessage 中,我使用该用户名将 websocket 保存在数组中,然后稍后通过用户名检索它:

wss.on('connection', function(ws) {

  ws.on('message', function(message) {

      users[message.userName] = ws;

(3) To send to a particular user you can then do users[userName].send(message);

(3) 要发送给特定用户,您可以执行 users[userName].send(message);

回答by Serhat Ates

you can use request header 'sec-websocket-key'

您可以使用请求标头“sec-websocket-key”

wss.on('connection', (ws, req) => {
  ws.id = req.headers['sec-websocket-key']; 

  //statements...
});

回答by rrkjonnapalli

You can check the connection object. It has built-in identification for every connected client; you can find it here:

您可以检查连接对象。它对每个连接的客户端都有内置的标识;你可以在这里找到它:

let id=ws._ultron.id;
console.log(id);

回答by cyberrspiritt

One possible solution here could be appending the deviceId in front of the user id, so we get to separate multiple users with same user id but on different devices.

一种可能的解决方案是将 deviceId 附加到用户 ID 之前,这样我们就可以将具有相同用户 ID 但在不同设备上的多个用户分开。

ws://xxxxxxx:9000/userID/<<deviceId>>

ws://xxxxxxx:9000/userID/<<deviceId>>

回答by Klaus Hessellund

I'm using fd from the ws object. It should be unique per client.

我正在使用 ws 对象中的 fd。每个客户端它应该是唯一的。

var clientID = ws._socket._handle.fd;

I get a different number when I open a new browser tab.

当我打开一个新的浏览器标签时,我得到了一个不同的数字。

The first ws had 11, the next had 12.

第一个 ws 有 11 个,下一个有 12 个。

回答by Deepak Chaudhary

By clients if you mean the open connections, then you can use ws.upgradeReq.headers['sec-websocket-key']as the identifier. And keep all socket objects in an array.

对于客户端,如果您指的是打开的连接,那么您可以将其ws.upgradeReq.headers['sec-websocket-key']用作标识符。并将所有套接字对象保存在一个数组中。

But if you want to identify your user then you'll need to add user specific data to socket object.

但是如果你想识别你的用户,那么你需要将用户特定的数据添加到套接字对象中。

回答by Marko Bala?ic

If someone here is maybe using koa-websocketlibrary, server instance of WebSocket is attached to ctxalong side the request. That makes it really easy to manipulate the wss.clientsSet (set of sessions in ws). For example pass parameters through URL and add it to Websocket instance something like this:

如果这里有人可能正在使用koa-websocket库,则 WebSocket 的服务器实例会附加到ctx请求旁边。这使得操作wss.clientsSet (ws 中的会话集)变得非常容易。例如,通过 URL 传递参数并将其添加到 Websocket 实例中,如下所示:

const wss = ctx.app.ws.server
const { userId } = ctx.request.query

try{

   ctx.websocket.uid = userId

}catch(err){
    console.log(err)
}