socket example ejemplo javascript html5 node.js websocket

javascript - example - ¿Enviando mensajes a usuarios específicos conectados usando webSocket?



websocket javascript ejemplo (3)

Aquí hay un simple mensaje privado / directo del servidor de chat.

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) }) })

Instrucciones

Para probarlo, ejecute npm install para instalar ws . Luego, para iniciar el servidor de chat, ejecute el node server.js (o npm start ) en una pestaña del Terminal. Luego, en otra pestaña Terminal, ejecute wscat -c ws://localhost:5000/1 , donde 1 es el ID de usuario del usuario que conecta. Luego, en una tercera pestaña Terminal, ejecute wscat -c ws://localhost:5000/2 , y luego, para enviar un mensaje del usuario 2 a 1 , ingrese ["1", "Hello, World!"] .

Deficiencias

Este servidor de chat es muy simple.

  • Persistencia

    No almacena mensajes en una base de datos, como PostgreSQL. Por lo tanto, el usuario al que envía un mensaje debe estar conectado al servidor para recibirlo. De lo contrario, el mensaje se pierde.

  • Seguridad

    Es inseguro

    • Si conozco la URL del servidor y la identificación de usuario de Alice, puedo suplantar a Alice, es decir, conectarme al servidor como ella, lo que me permite recibir sus nuevos mensajes entrantes y enviar mensajes de ella a cualquier usuario cuya ID de usuario también conozca. Para hacerlo más seguro, modifique el servidor para aceptar su token de acceso (en lugar de su ID de usuario) al conectarse. Luego, el servidor puede obtener su ID de usuario de su token de acceso y autenticarlo.

    • No estoy seguro si es compatible con una conexión WebSocket Secure ( wss:// ) ya que solo lo he probado en localhost , y no estoy seguro de cómo conectar de forma segura desde localhost .

Escribí un código para transmitir un mensaje a todos los usuarios:

El código usado: (breve)

// 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 por favor :

  • No tengo ninguna referencia de usuario sino solo una conexión.
  • La conexión de todos los usuarios se almacena en una array .

Objetivo : digamos que el servidor de NodeJs quiere enviar un mensaje a un cliente específico (John).

Y aquí está la pregunta:

  • ¿Cómo sabría el servidor de NodeJs qué conexión tiene John?

    El servidor de NodeJs ni siquiera conoce a John. todo lo que ve son las conexiones.

Por lo tanto, creo que ahora, no debería almacenar usuarios solo por su conexión. En su lugar, necesito almacenar un objeto , que contendrá el userId y el objeto de connection .

Y aquí está mi idea:

  • Cuando la página termine de cargarse (Dom ready), establezca una conexión con el servidor NodeJs.

  • Cuando el servidor NodeJs acepta una conexión, genere una cadena única y envíela al navegador del cliente. Almacene la conexión de usuario y la cadena única en un objeto. por ejemplo, {UserID:"6" , value :{connectionObject}}

  • En el lado del cliente, cuando llega este mensaje, guárdelo en un campo oculto o una cookie. (para futuras solicitudes al servidor NodeJs)

Cuando el servidor quiere enviar un mensaje a John:

  • Encuentre el ID de usuario de John en el diccionario y envíe un mensaje por la conexión correspondiente.

tenga en cuenta que no hay ningún código de servidor asp.net aquí invocado (en el mecanismo de mensaje). solo NodeJs.

Pregunta:

¿Es este el camino correcto? (¿o me he perdido algo?)


Este no es solo el camino correcto, sino el único. Básicamente, cada conexión necesita una identificación única. De lo contrario, no podrá identificarlos, es así de simple.

Ahora cómo lo representarás es algo diferente. Hacer un objeto con propiedades de id y connection es una buena manera de hacerlo (definitivamente, lo conseguiría). También puede adjuntar la id directamente al objeto de conexión.

También recuerde que si desea comunicación entre usuarios, también debe enviar la ID del usuario objetivo, es decir, cuando el usuario A desea enviar un mensaje al usuario B, obviamente A debe saber la ID de B.


Me gustaría compartir lo que he hecho. Espero que no pierda tu tiempo.

Creé una tabla de base de datos que contenía ID de campo, IP, nombre de usuario, logintime y logouttime. Cuando un usuario inicie sesión en logintime, estará en currect unixtimestamp unix. Y cuando se inicia la conexión en la base de datos websocket, se comprueba el logintime más grande. Será ingresado al usuario.

Y para cuando el usuario cierre la sesión, almacenará el tiempo de cierre de sesión correcto. El usuario se convertirá en quien dejó la aplicación.

Siempre que haya un nuevo mensaje, se compararán la ID de Websocket y la IP, y se mostrará el nombre de usuario relacionado. Los siguientes son código de muestra ...

// 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 }