Sending a message to specific connected users using webSocket?

I wrote code to broadcast the message to all users:

Used code: (short)

// websocket and http servers var webSocketServer = require('websocket').server; ... ... var clients = [ ]; var server = http.createServer(function(request, response) { // Not important for us. We're writing WebSocket server, not HTTP server }); server.listen(webSocketsServerPort, function() { ... }); var wsServer = new webSocketServer({ // WebSocket server is tied to a HTTP server. httpServer: server }); // This callback function is called every time someone // tries to connect to the WebSocket server wsServer.on('request', function(request) { ... var connection = request.accept(null, request.origin); var index = clients.push(connection) - 1; ... 

Note:

  • I do not have a user link, but only a connection.
  • All user connections are stored in array .

Purpose : say that the NodeJs server wants to send a message to the client specific (John).

And here is the question:

  • How does the NodeJs server know which connection John has?

    NodeJs server doesn't even know John. all he sees is connections.

So, I believe that now I do not have to store users only by their connection, instead I need to save an object that will contain the userId and connection object.

And here is my idea:




  • When the page load finishes (Dom ready) - establish a connection to the NodeJs server.

  • When the NodeJs server accepts the connection, it generates a unique string and sends it to the client browser. Store the user connection and unique string in the object. e.g. {UserID:"6" , value :{connectionObject}}

  • On the client side, when this message arrives, save it in a hidden field or in a cookie. (for future requests to the NodeJs server)




When the server wants to send a message to John:

  • Find john UserID in the dictionary and send a message to the appropriate connection.

Note that there is no asp.net server code that is located here (in the message engine). NodeJs only.

Question:

Is this the right way? (or am I missing something?)

+64
javascript html5 websocket
Apr 29 '13 at
source share
4 answers

This is not only the right way, but the only way. Basically, each connection requires a unique identifier. Otherwise, you cannot identify them; it is so simple.

Now, as you imagine it, this is another matter. Creating an object with id and connection properties is a good way to do this (I would definitely go for it). You can also bind id to the connection object.

Also remember that if you want to communicate between users, you also need to send the target user ID, that is, when user A wants to send a message to user B, then obviously A must know the identifier B.

+63
May 01 '13 at 14:28
source share

Here's a simple chat server for private / direct messages.

package.json

 { "name": "chat-server", "version": "0.0.1", "description": "WebSocket chat server", "dependencies": { "ws": "0.4.x" } } 

server.js

 var webSocketServer = new (require('ws')).Server({port: (process.env.PORT || 5000)}), webSockets = {} // userID: webSocket // CONNECT /:userID // wscat -c ws://localhost:5000/1 webSocketServer.on('connection', function (webSocket) { var userID = parseInt(webSocket.upgradeReq.url.substr(1), 10) webSockets[userID] = webSocket console.log('connected: ' + userID + ' in ' + Object.getOwnPropertyNames(webSockets)) // Forward Message // // Receive Example // [toUserID, text] [2, "Hello, World!"] // // Send Example // [fromUserID, text] [1, "Hello, World!"] webSocket.on('message', function(message) { console.log('received from ' + userID + ': ' + message) var messageArray = JSON.parse(message) var toUserWebSocket = webSockets[messageArray[0]] if (toUserWebSocket) { console.log('sent to ' + messageArray[0] + ': ' + JSON.stringify(messageArray)) messageArray[0] = userID toUserWebSocket.send(JSON.stringify(messageArray)) } }) webSocket.on('close', function () { delete webSockets[userID] console.log('deleted: ' + userID) }) }) 

instructions

To verify this, run npm install to install ws . Then, to start the chat server, run node server.js (or npm start ) on one tab "Terminal". Then on another tab “Terminal” run wscat -c ws://localhost:5000/1 , where 1 is the user ID of the connecting user. Then, in the third tab “Terminal”, run wscat -c ws://localhost:5000/2 , and then to send a message from user 2 to 1 , enter ["1", "Hello, World!"] .

Omissions

This chat server is very simple.

  • Tenacity

    It does not store messages in a database such as PostgreSQL. Thus, the user to whom you send the message must be connected to the server to receive it. Otherwise, the message will be lost.

  • Security

    It is not safe.

    • If I know the server URL and Alice’s user ID, then I can impersonate Alice, that is, connect to the server like her, which will allow me to receive her new incoming messages and send messages from her to any user whose user ID I also know . To make it more secure, change the server so that it accepts your access token (instead of your user ID) when connecting. The server can then retrieve your user ID from your access token and authenticate you.

    • I'm not sure if it supports a WebSocket Secure ( wss:// ) connection, as I only tested it on localhost wss:// and not sure how to connect securely with localhost .

+32
Oct 19 '13 at 18:05
source share

I would like to share what I have done. Hope this does not waste your time.

I created a database table containing the field identifier, IP, username, login time and logout time. When a user logs in to logintime, unixtimestamp unix correction will be performed. And when the connection is started in the websocket database, a check is performed for the longest login time. He will log in.

And when the user logs out, he will save the registration time. The user will become the one who left the application.

Whenever a new message appears, the Websocket ID and IP address are compared and the username associated with it is displayed. Below is sample code ...

 // when a client connects function wsOnOpen($clientID) { global $Server; $ip = long2ip( $Server->wsClients[$clientID][6] ); require_once('config.php'); require_once CLASSES . 'class.db.php'; require_once CLASSES . 'class.log.php'; $db = new database(); $loga = new log($db); //Getting the last login person time and username $conditions = "WHERE which = 'login' ORDER BY id DESC LIMIT 0, 1"; $logs = $loga->get_logs($conditions); foreach($logs as $rows) { $destination = $rows["user"]; $idh = md5("$rows[user]".md5($rows["time"])); if ( $clientID > $rows["what"]) { $conditions = "ip = '$ip', clientID = '$clientID' WHERE logintime = '$rows[time]'"; $loga->update_log($conditions); } } ...//rest of the things } 
+1
Jul 28 '15 at 9:32
source share

interesting post (similar to what I'm doing). We create an API (in C #) for connecting dispensers with WebSockets, for each dispenser we create a ConcurrentDictionary, which stores WebSocket and DispenserId, which makes it easy for each dispenser to create a WebSocket and then use it without problems with threads (calling certain functions on WebSocket, like GetSettings or RequestTicket). The difference for you in this example is to use a ConcurrentDictionary instead of an array to isolate each element (never tried to do this in javascript). Regards,

0
Jun 12 '19 at 11:39 on
source share



All Articles