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, у которого открыт его сокет.
Ответы
Ответ 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>>