0

From the HTML file I am sending message using webSocket.

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

token will come from browser 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);

I have opened 3 browsers with following URL

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

Messages are being received in all browsers. If message is send from send_token I want message to be received only by browser with same_token

3
  • Please review the answer I linked you to. You have to bind ws to a token indexed array of clients, then you can send the message to the array of users webSockets[userToken] = ws. var toUserWebSocket = webSockets[token] toUserWebSocket.send(message) Commented Jun 20, 2021 at 6:23
  • I tried that method already, it is also passing message to everyone Commented Jun 20, 2021 at 14:43
  • I am not able to reproduce the issue. What does the client side code look like? Also what does console.log(userToken) and console.log(token) output? Commented Jun 20, 2021 at 16:18

1 Answer 1

1

I was not able to reproduce the issue as described, but was only able to receive the sent message to only one of the connected clients with the same token.

The issue with the single connected client is due to webSockets[userToken] = ws being referenced, as opposed to using an array of clients webSockets[userToken] = []; and webSockets[userToken].push(ws);

Also be sure that you do not have a zombie process of node server.js running in the background.

//...

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 code

<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>
Sign up to request clarification or add additional context in comments.

3 Comments

Sorry, I could check your answer only today. I am not sure if your answer is working or not. I am getting 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
It is probably related to something with the data being sent from the client.. I copy/pasted the code I was using to test with. Would need to know which line the error was on to validate.
Anyways thank you for your assist. It was difficult time learning websocket(node) for first time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.