如何使用 websocket 在具有相同令牌的用户之间发送消息?

How to send message between users with same token using websocket?

我正在使用 webSocket 从 HTML 文件发送消息。

const socket = new WebSocket("ws://localhost:3000/{{ token }}");
socket.send(JSON.stringify(message));

token 将来自浏览器 URL.

server.js

const WebSocket = require('ws');
const qs = require('querystring');
const http = require('http');
const wss = new WebSocket.Server({ port: 3000 });
const webSockets = {};


wss.on('connection', function (ws, req)
{
    let url = req.url;
    let userToken = url.substring(url.lastIndexOf('/') + 1);
    webSockets[userToken] = ws;
    
    ws.on('message', function incoming(message)
    {
        let messageArray = JSON.parse(message);
        let token = messageArray['token'];
        let toUserWebSocket = webSockets[token];
        toUserWebSocket.send(message);

我打开了 3 个浏览器 URL

`https://url/same_token`
`https://url/same_token`
`https://url/different_token`

正在所有浏览器中接收消息。如果消息是从 send_token 发送的,我希望消息只能由具有 same_token

的浏览器接收

我无法重现所描述的问题,但只能收到发送给具有相同 token.

的已连接客户端之一的发送消息

单个连接客户端的问题是由于引用了 webSockets[userToken] = ws,而不是使用客户端数组 webSockets[userToken] = [];webSockets[userToken].push(ws);

还要确保后台没有 node server.js 运行 的僵尸进程。

//...

const clients = {};

wss.on('connection', function connection(ws, req) {
    let id = req.url.substring(req.url.lastIndexOf('/') + 1);
    if ('' === id) {
        //connecting id is missing
        ws.terminate();

        return;
    }
    if ('undefined' === typeof clients[id]) {
        clients[id] = [];
    }
    console.log('Connection Received from IP: ' + req.socket.remoteAddress + ' with id ' + id);

    //append websocket client to list of clients
    clients[id].push(ws);

    ws.on('message', function incoming(message) {
        if ('' === message) {
            //skip if message is blank
            return;
        }

        try {
            //process message as JSON object as "{"message": "string", "token": "string"}"
            message = JSON.parse(message);
        } catch(e) {
            return;
        }

        if (!message.hasOwnProperty('token') || '' === message.token) {
            //token was not sent or is empty
            return;
        }
        let token = message.token;
        console.log('Message received for token ' + token);

        if ('undefined' !== typeof clients[token] && clients[token]) {
            clients[token].forEach(function(client) {
                if (client !== ws && client.readyState === WebSocket.OPEN) {
                    //do not send message back to the sending client
                    client.send(message.message + ' ' + token);
                }
            });
        }

        //inform sending client message was sent
        ws.send('Sent: ' + message.message);
    });

    ws.on('close', function() {
        clients[id].forEach(function(client, index) {
            if (client === ws) {
                //remove the client from the pool
                clients[id].splice(index, 1);
            }
        });
    });
});

html代码

<button type="button" id="sendBtn" class="btn-primary">Send</button>

<script type="text/javascript">
    const socket = new WebSocket('ws://localhost:8080/{{ token }}');
    socket.onmessage = function(evt) {
        window.console.log(evt.data);
    };

    jQuery(function($) {
        $('#sendBtn').on('click', function() {
            const message = {
                "message": "Hello World",
                "token": "{{ token }}"
            };
            socket.send(JSON.stringify(message));
        });
    });
</script>