Skip to content Skip to sidebar Skip to footer

Websockets: Send Messages And Notifications To All Clients Except Sender

I am developing chat based on websockets and webrtc. I would like to send messages to all connected users except sender but I cannot find suitable solution. To be more specific, I

Solution 1:

Here is a very simple way of sending to everyone connected except the sender.

Create a broadcast function on your webSocketServer instance that will take two params.

...
var webSocketServer = new WebSocketServer.Server({ port: 8081 });
...
/*
 * method: broadcast
 * @data: the data you wanna send
 * @sender: which client/ws/socket is sending
 */
webSocketServer.broadcast = function(data, sender) {
  webSocketServer.clients.forEach(function(client) {
    if (client !== sender) {
      client.send(data)
    }
  })
}

...
// On your message callback.
ws.on('message', function(message) {
 ...
  // Note that we're passing the (ws) here
  webSocketServer.broadcast(message, ws);
})

That's it, the broadcast method will send to each connected client except the one who is sending.

Solution 2:

Ok, so we are now storing the CLIENTS in a way that allows us to uniquely identify each client that is connecting, and store arbitrary information about them for later retrieval.

The code below will send the "notes" message to all clients, and THEN add the newly connecting client to the "all clients" list.

SERVER.JS:

var http = require('http'),
    Static = require('node-static'),
    WebSocketServer = newrequire('ws'),

    // list of users/*
        We are now storing client data like this:

        CLIENTS = {

            uniqueRandomClientID: {

                socket: {},         // The socket that this client is connected on
                clientDetails: {    // Any details you might wish to store about this client

                    username: "",
                    etc: "etc"
                }
            }
        };

        So now to get at the socket for a client, it'll be: CLIENTS[uniqueRandomClientID].socket.
        Or to show a client's username, it'll be: CLIENTS[uniqueRandomClientID].clientDetails.username.
        You might want to write a 'getClientByUsername' function that iterates the CLIENTS array and returns the client with that username.
    */CLIENTS = {},

    // web server is using 8081 port
    webSocketServer = newWebSocketServer.Server({ port: 8081 });

// check if connection is established
webSocketServer.on('connection', function(ws) {

    console.log('connection is established');

    // Now using a randomly generated ID to reference a client. Probably should be better than Math.random :Dvar wsID = Math.floor(Math.random() * 1000);

    ws.on('message', function(message) {

        console.log('received: %s', message);
        var received = JSON.parse(message);

        if(received.type == "login"){

            // If a client with this login name doesnt exist already, its a new clientif(!CLIENTS[wsID]) {

                doBroadcast(
                    {
                        "newuser": received.name,
                        type: "notes"
                    }
                );

                // Now add this new client to the listCLIENTS[wsID] = {

                    socket: ws,
                    clientDetails: {

                        username: received.name
                    }
                };
            }
        } elseif(received.type == "message") {

            doBroadcast(message); // broadcast messages to everyone including sender
        }
    });

    ws.on('close', function(_event) {

        if(CLIENTS[wsID]) {

            console.log('user ' + CLIENTS[wsID].clientDetails.username + ' left chat');
            deleteCLIENTS[wsID];
        }
    });

    /*
    * Added this to 'catch' errors rather than just red dump to console. I've never actually done anything with this myself (I *like* red text in my console), but I know this handler should be here :P
    */
    ws.on('error', function(_error) {

        console.log("error!");
        console.log(_error);
    });

    /*
    * Send an object to a client
    *
    * @param WebSocketClient _to - The client you want to send to (generally an index in the CLIENTS array, i.e CLIENTS["bobsusername123"]
    * @param Object _message - A stringifyable JSON object. Complex ones can screw things up, but your basic key/value pairs are usually fine to send.
    */functiondoSend(_to, _message) {

        _to.send(JSON.stringify(_message));
    };

    // Added broadcast function to replace sendAll// Notice how it JSON stringifies the data before sending/*
    * Broadcast a message to all clients
    *
    * @param Object _message - A stringifyable JSON object. Complex ones can screw things up, but your basic key/value pairs are usually fine to send.
    */functiondoBroadcast(_message) {

        for(var client inCLIENTS) {

            if(!CLIENTS.hasOwnProperty(client)) continue;

            doSend(CLIENTS[client].socket, _message);
        }
    };
});

var fileServer = newStatic.Server('.');
http.createServer(function (req, res) {

    fileServer.server(req, res);

}).listen(8080, function(){
    console.log("Server is listening 8080 port.");
});

console.log("Server is running on 8080 and 8081 ports");

MY CLIENT.JS (for your reference):

var loginButton = document.getElementById("loginbutton"),
    usernameInput = document.getElementById("usernameInput");

varSocketClient = function(_uri, _callbacks) {

    this.uri = _uri;
    this.callbacks = _callbacks;
};

SocketClient.prototype = {

    send: function(_message) {

        this.socket.send(_message);
    },

    connect: function() {

        try {

            this.socket = newWebSocket("ws://" + this.uri);
        } catch(e) { returnfalse; }

        for(var callback inthis.callbacks) {

            if(!this.callbacks.hasOwnProperty(callback)) continue;
            this.socket["on" + callback] = this.callbacks[callback];
        }

        returntrue;
    }
};

var socketClient = newSocketClient(

    "127.0.0.1:8081",
    {
        open: function() {

            console.log("connected.");
        },
        message: function(_message) {

            console.log("received data:");
            console.log(_message);
        },
        close: function() {

            console.log("closed.");
        },
        error: function(_error) {

            console.log("error: ");
            console.log(_error);
        }
    }
);

socketClient.connect();

loginButton.addEventListener("click", function(){

    name = usernameInput.value;

    if(name.length > 0){

        socketClient.send(JSON.stringify({
            type: "login",
            name: name
        }));
    }

});

AND THE CLIENT.HTML TO GO WITH IT:

<!DOCTYPE html><html><head><metacharset="utf-8"/></head><body><inputtype="text"id="usernameInput"/><buttontype="button"id="loginbutton">Login</button><scriptsrc="client.js"></script></body></html>

Ive tested this with NWJS v0.12.3 running the server and Firefox on the client.

Solution 3:

This should work

constWebSocket = require('ws');

// Websocket variablesconst wss = newWebSocket.Server({
    port: 3000
});
console.log('Websocket active on port 3000...');


// New WebSocket Connection
wss.on('connection', functionconnection(ws) {

    console.log('new connection')

    // On Message Received
    ws.on('message', functionincoming(message) {

        console.log(message)
        
        // Send To Everyone Except Sender
        wss.clients.forEach(function(client) {
            if (client !== ws) client.send(message);
        });

    });


});

Post a Comment for "Websockets: Send Messages And Notifications To All Clients Except Sender"