web-dev-qa-db-ja.com

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を介してサーバーにメッセージを送信し、ソケットを開いているuser2に通知を送信したいと思います。

53
Ajouve

単純に配列CLIENTS []にユーザーIDを割り当てることができます。これにはすべてのユーザーが含まれます。以下のように、すべてのユーザーにメッセージを直接送信できます。

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);
    }
}
47
Ankit Bisht

Nodejsでは、wsクライアントを直接変更し、各クライアントのカスタム属性を個別に追加できます。また、グローバル変数wss.clientsがあり、どこでも使用できます。次のコードを試して、少なくとも2つのクライアントに接続してみてください。

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;
}
49
Jzapata

このコードスニペット 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()関数を簡単に作成できるようになりました。

お役に立てば幸いです。

8
H Dog

使用している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)特定のユーザーに送信するには、users [userName] .send(message);を実行します。

8
droid-zilla

要求ヘッダー 'sec-websocket-key'を使用できます

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

  //statements...
});
4
Serhat Ates

接続オブジェクトを確認できます。接続されているすべてのクライアントのIDが組み込まれています。ここで見つけることができます:

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

Wsオブジェクトのfdを使用しています。クライアントごとに一意である必要があります。

var clientID = ws._socket._handle.fd;

新しいブラウザタブを開くと、異なる番号が表示されます。

最初のWSには11があり、次のWSには12がありました。

2

ここで考えられる解決策の1つは、ユーザーIDの前にdeviceIdを追加することです。そのため、同じユーザーIDで異な​​るデバイス上の複数のユーザーを分離できます。

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

2
cyberrspiritt

クライアントが開いた接続を意味する場合、ws.upgradeReq.headers['sec-websocket-key']識別子として。そして、すべてのソケットオブジェクトを配列に保持します。

ただし、ユーザーを特定する場合は、ユーザー固有のデータをソケットオブジェクトに追加する必要があります。

0

ここの誰かが多分 koa-websocket ライブラリを使用している場合、WebSocketのサーバーインスタンスはリクエストと一緒にctxにアタッチされます。これにより、wss.clientsセット( ws のセッションのセット)。たとえば、URLを介してパラメーターを渡し、次のようなWebsocketインスタンスに追加します。

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

try{

   ctx.websocket.uid = userId

}catch(err){
    console.log(err)
}
0
Marko Balažic