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に通知を送信したいと思います。
単純に配列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);
}
}
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;
}
このコードスニペット 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()関数を簡単に作成できるようになりました。
お役に立てば幸いです。
使用している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);を実行します。
要求ヘッダー 'sec-websocket-key'を使用できます
wss.on('connection', (ws, req) => {
ws.id = req.headers['sec-websocket-key'];
//statements...
});
接続オブジェクトを確認できます。接続されているすべてのクライアントのIDが組み込まれています。ここで見つけることができます:
let id=ws._ultron.id;
console.log(id);
Wsオブジェクトのfdを使用しています。クライアントごとに一意である必要があります。
var clientID = ws._socket._handle.fd;
新しいブラウザタブを開くと、異なる番号が表示されます。
最初のWSには11があり、次のWSには12がありました。
ここで考えられる解決策の1つは、ユーザーIDの前にdeviceIdを追加することです。そのため、同じユーザーIDで異なるデバイス上の複数のユーザーを分離できます。
ws://xxxxxxx:9000/userID/<<deviceId>>
クライアントが開いた接続を意味する場合、ws.upgradeReq.headers['sec-websocket-key']
識別子として。そして、すべてのソケットオブジェクトを配列に保持します。
ただし、ユーザーを特定する場合は、ユーザー固有のデータをソケットオブジェクトに追加する必要があります。
ここの誰かが多分 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)
}