Подтвердить что ты не робот

WebsocketServer node.js как дифференцировать клиентов

Я пытаюсь использовать сокеты с 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');
});

Этот код отлично работает с моим клиентом js.

Но я хотел бы отправить сообщение определенному пользователю или всем пользователям, имеющим сокеты, открытые на моем сервере.

В моем случае я отправляю сообщение как клиент, и я получаю ответ, но остальные пользователи ничего не показывают.

Я хотел бы, например, user1 отправляет сообщение на сервер через webSocket, и я отправляю уведомление пользователю2, у которого открыт его сокет.

4b9b3361

Ответ 1

Вы можете просто назначить идентификатор пользователей массиву 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);
    }
}

Ответ 2

Этот фрагмент кода на сервере 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];

Теперь вы можете легко создать функцию broadcast() и sendToConnectionId(), как показано в связанном коде.

Надеюсь, что это поможет.

Ответ 3

Это зависит от того, какой 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);
 });
};

Затем в вашем коде вы можете использовать wss.broadcast(message) для отправки всем. Для отправки PM отдельному пользователю я делаю следующее:

(1) В моем сообщении, которое я отправляю на сервер, я включаю имя пользователя (2) Затем в onMessage я сохраняю websocket в массиве с этим именем пользователя, а затем извлекаю его по имени пользователя позже:

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

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

      users[message.userName] = ws;

(3) Чтобы отправить конкретному пользователю, вы можете затем выполнить пользователя [имя_пользователя].send(сообщение);

Ответ 4

В 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);
    });
});

Вы также можете передавать параметры непосредственно в URL-адресе клиента:

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

В функции соединения вы можете получить эти параметры и назначить эти параметры непосредственно своему клиенту 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;
}

Ответ 5

Вы можете проверить объект соединения. Он имеет встроенную идентификацию для каждого подключенного клиента; вы можете найти его здесь:

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

Ответ 6

Я использую fd из объекта ws. Он должен быть уникальным для каждого клиента.

var clientID = ws._socket._handle.fd;

При открытии новой вкладки браузера я получаю другое число.

Первый ws имел 11, следующий имел 12.

Ответ 7

Клиентами, если вы имеете в виду открытые соединения, тогда вы можете использовать ws.upgradeReq.headers['sec-websocket-key'] в качестве идентификатора. И сохраните все объекты сокетов в массиве.

Но если вы хотите идентифицировать своего пользователя, вам нужно будет добавить данные, специфичные для пользователя, в объект сокета.

Ответ 8

Одним из возможных решений может быть добавление deviceId перед идентификатором пользователя, поэтому мы можем разделить несколько пользователей с одинаковым идентификатором пользователя, но на разных устройствах.

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