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

Posted

技术标签:

【中文标题】如何使用 websocket 在具有相同令牌的用户之间发送消息?【英文标题】:How to send message between users with same token using websocket? 【发布时间】:2021-09-04 05:39:28 【问题描述】:

从我使用 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 的浏览器接收

【问题讨论】:

请查看answer I linked you to。您必须将 ws 绑定到一个令牌索引的客户端数组,然后您可以将消息发送到用户数组webSockets[userToken] = wsvar toUserWebSocket = webSockets[token]toUserWebSocket.send(message) 这个方法我已经试过了,也是给大家传递信息 我无法重现该问题。客户端代码是什么样的?还有console.log(userToken)console.log(token) 输出什么? 【参考方案1】:

我无法重现所描述的问题,但只能将发送的消息接收到具有相同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>

【讨论】:

抱歉,我只能在今天查看您的答案。我不确定您的答案是否有效。我收到TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object 这可能与从客户端发送的数据有关。我复制/粘贴了我用来测试的代码。需要知道要验证的错误发生在哪一行。 无论如何感谢您的协助。第一次学习 websocket(node) 很困难

以上是关于如何使用 websocket 在具有相同令牌的用户之间发送消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何将消息传递给websocket?

如何使用令牌获取有关用户的信息

使用令牌的 websocket 授权

如何在 Node JS 中使用 jwt 授权具有不同令牌的所有用户

如何跟踪具有访问令牌的用户是否仍具有有效会话?

如何在主 iOS 应用程序及其共享扩展程序之间使用相同的经过身份验证的用户令牌