{"id":1676,"date":"2021-04-01T00:20:44","date_gmt":"2021-04-01T06:20:44","guid":{"rendered":"https:\/\/www.jacobsoft.com.mx\/?p=1676"},"modified":"2025-02-20T13:37:48","modified_gmt":"2025-02-20T19:37:48","slug":"implementacion-de-websockets-con-node-js","status":"publish","type":"post","link":"https:\/\/www.jacobsoft.com.mx\/es_mx\/implementacion-de-websockets-con-node-js\/","title":{"rendered":"Implementaci\u00f3n de WebSockets con Node.js"},"content":{"rendered":"\n<p><strong>WebSocket <\/strong>es un protocolo de comunicaci\u00f3n sobre una <strong>conexi\u00f3n TCP<\/strong> que establece un canal bidireccional o <strong>full-duplex<\/strong> con m\u00ednima latencia entre el <strong>servidor <\/strong>y el <strong>navegador<\/strong>. El navegador utiliza javascript y la API de Websocket soportada por todos los navegadores y del lado del servidor, vamos a implementar el esquema de Websockets con Node.js<\/p>\n\n\n\n<p>El protocolo Websocket fue estandarizado por la <a href=\"https:\/\/en.wikipedia.org\/wiki\/Internet_Engineering_Task_Force\" target=\"_blank\" rel=\"noreferrer noopener\">IETF <\/a>e 2011 como RFC 6455 y la API de Websocket por la <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/web-sockets.html\" target=\"_blank\" rel=\"noreferrer noopener\">W3C<\/a>.<\/p>\n\n\n\n<p>Este protocolo es diferente al protocolo HTTP aunque ambos son de la capa 7 en el modelo OSI y dependen de la capa 4 TCP. Websocket esta dise\u00f1ado para operar sobre HTTP en los puertos 443 y 80 al mismo tiempo de soportar proxies e intermediarios. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Funcionalidad<\/h2>\n\n\n\n<p>El punto interesante es que el protocolo <strong>Websocket <\/strong>habilita la interacci\u00f3n entre un <strong>navegador web<\/strong> o cualquier otra aplicaci\u00f3n cliente y un <strong>servidor web<\/strong> con baja sobrecarga facilitando la transferencia de datos en <strong>tiempo real<\/strong> desde y hacia el servidor. Esto se hace posible con una forma estandarizada de enviar contenido del servidor al cliente sin que el cliente inicie la petici\u00f3n y permite enviar mensajes de regreso y hacia adelante manteniendo la <strong>conexi\u00f3n abierta<\/strong>. Por lo que se puede establecer una <strong>comunicaci\u00f3n bidireccional<\/strong> entre el cliente y el servidor. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"245\" src=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo-1024x245.png\" alt=\"Websockets con Node.js\" class=\"wp-image-1684\" srcset=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo-1024x245.png 1024w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo-300x72.png 300w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo-768x184.png 768w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo-16x4.png 16w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo-251x60.png 251w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Sin-titulo.png 1075w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>En consecuencia, la mayor\u00eda de los navegadores soportan el protocolo Websocket a trav\u00e9s de la directiva ws:\/\/ y para el protocolo seguro la directiva es wss:\/\/ como esquemas de URI (Uniform Resource Identifier).<\/p>\n\n\n\n<p>Para su implementaci\u00f3n se utiliza <strong>Javascript <\/strong>del lado del <strong>cliente <\/strong>en una p\u00e1gina web que invoca funciones a trav\u00e9s de los eventos de la p\u00e1gina y del lado del servidor se pueden utilizar diversos lenguajes de programaci\u00f3n entre los cuales podemos mencionar C#, Java, PHP, Python y por supuesto <strong>Javascript <\/strong>con <strong>Node <\/strong>y en nuestro caso utilizaremos el paquete de websockets.<\/p>\n\n\n\n<p>Para el manejo de los Sockets, del lado del <strong>cliente <\/strong>existen dos grupos de funciones: 1) las requeridas para administrar el <strong>ciclo de vida del objeto<\/strong> y 2) los <strong>callbacks<\/strong>, que son las funciones que el navegador va a invocar cuando detecte un evento relacionado con el Websocket.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-2380084220870127\"\n     crossorigin=\"anonymous\"><\/script>\n<ins class=\"adsbygoogle\"\n     style=\"display:block; text-align:center;\"\n     data-ad-layout=\"in-article\"\n     data-ad-format=\"fluid\"\n     data-ad-client=\"ca-pub-2380084220870127\"\n     data-ad-slot=\"2437322509\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ciclo de vida<\/h3>\n\n\n\n<p>En <strong>primer lugar<\/strong> se crea el WebSocket, lo m\u00e1s recomendable es que sea al terminar de cargarse la p\u00e1gina, dentro de la funci\u00f3n onload() del objeto window.<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>var socket = new WebSocket(\"ws:\/\/servidor.com\/socketserver\");<\/code><\/pre>\n\n\n\n<p>El objeto Websocket recibe en el constructor \u00fanicamente la URL del servidor al que nos vamos a conectar. La directiva ws:\/\/ reemplaza a http:\/\/ y si requerimos un canal seguro, entonces usamos wss:\/\/<\/p>\n\n\n\n<p>Para enviar mensajes al servidor utilizamos el m\u00e9todo send:<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>socket.send(\"Mensaje para el servidor\");<\/code><\/pre>\n\n\n\n<p>El m\u00e9todo send recibe una cadena con el mensaje que se enviar\u00e1 al servidor.<\/p>\n\n\n\n<p>Si deseamos enviar un objeto JSON podemos hacerlo de la siguiente forma:<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>var mensaje = {\n          nombre: \"Enrique Mart\u00ednez\",\n          correo: \"enrique@gmail.com\",\n          edad: 30\n        };\nsocket.send(JSON.stringify(mensaje));<\/code><\/pre>\n\n\n\n<p>Con la funci\u00f3n JSON.stringify convertimos el objeto JSON en una cadena, que es lo que recibe el m\u00e9todo send. Cuando sea necesario cerrar la conexi\u00f3n de manera explicita invocamos:<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>socket.close();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Eventos<\/h3>\n\n\n\n<p>Debido a que los Websockets funcionan de manera <strong>as\u00edncrona<\/strong>, es decir, que la aplicaci\u00f3n no se queda esperando en una l\u00ednea a que llegue el mensaje del servidor, sino que en el momento en que llega un mensaje del servidor, el navegador lo notifica invocando un funci\u00f3n de <strong>callback<\/strong>. De esta manera la aplicaci\u00f3n no se queda bloqueada y sigue respondiendo a las interacciones del usuario mientras se interact\u00faa con el servidor.<\/p>\n\n\n\n<p>Los eventos del <strong>Websocket <\/strong>son los siguientes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>onmessage<\/li><li>onopen<\/li><li>onclose<\/li><li>onerror<\/li><\/ul>\n\n\n\n<p>Las funciones de callback que se implementan para cada uno de los eventos reciben el objeto event, con el cual obtenemos la informaci\u00f3n correspondiente al evento. El <strong>mensaje <\/strong>recibido desde el servidor lo obtenemos con <strong>event.data<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>socket.onopen = function(evt){ alert(\"Conexi\u00f3n establecida\"); ...};\n\nsocket.onmessage = function(evt){ alert(\"Mensaje redibido: \" + evt.data); ...};\n\nsocket.onclose = function(evt){ alert(\"Conexi\u00f3n cerrada\"); ...};<\/code><\/pre>\n\n\n\n<div style=\"color:#ddd\" class=\"wp-block-genesis-blocks-gb-spacer gb-block-spacer gb-divider-solid gb-divider-size-1\"><hr style=\"height:54px\"\/><\/div>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Ejercicio Pr\u00e1ctico Websockets con Node.js<\/h2>\n\n\n\n<p>En primer lugar, empezaremos con la p\u00e1gina <strong>html<\/strong> que realiza la conexi\u00f3n al servidor de <strong>websockets<\/strong>. El archivo tiene el nombre: <strong>index.htm<\/strong>l y se puede colocas en la carpeta <strong>public <\/strong>dentro del proyecto de node o puede ser un archivo de una aplicaci\u00f3n o sitio web distinto. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cliente WebSockets<\/h3>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:markup language-markup\"><code>\n\n    \n        &lt;meta charset=\"utf-8\">\n        &lt;title>Mensajes con WebSockets&lt;\/title>\n        &lt;script src=\"js\/funciones.js\">&lt;\/script>\n        &lt;link href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.0.0-beta3\/dist\/css\/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-eOJMYsd53ii+scO\/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6\" crossorigin=\"anonymous\">\n    \n    \n        &lt;div class=\"container\">\n            &lt;h2>Implementando Websockets con Node.js&lt;\/h2>\n            &lt;div class=\"row mt-4\">\n                &lt;div class=\"col-sm-6\">\n                    &lt;label class=\"form-label\">Mensajes del servidor&lt;\/label>\n                    &lt;textarea id=\"mensajes\" rows=\"10\" cols=\"10\" class=\"form-control\">&lt;\/textarea>\n                &lt;\/div>\n                &lt;div class=\"col-sm-5\">\n                    &lt;form onsubmit=\"enviarTexto(event)\">\n                        &lt;label class=\"form-label\">Texto a enviar&lt;\/label>\n                        &lt;input type=\"text\" id=\"texto\" name=\"texto\" class=\"form-control\">\n                        &lt;button type=\"submit\" id=\"enviar\" class=\"btn btn-primary mt-2\">Enviar&lt;\/button>\n                    &lt;\/form>\n                &lt;\/div>\n            &lt;\/div>\n        &lt;\/div>\n    \n<\/code><\/pre>\n\n\n\n<p>En la secci\u00f3n del <strong>head <\/strong>se esta incorporando un archivo de <strong>javascript <\/strong>ubicado en la carpeta js con el nombre funciones.js, posteriormente se incorpora una etiqueta <strong>link <\/strong>para agregar la hoja de estilos de <strong>Bootstrap <\/strong>directamente del cdn de bootstrap para darle formato a la p\u00e1gina sin agregar tanto c\u00f3digo. <\/p>\n\n\n\n<p>El cuerpo de la p\u00e1gina creamos dos columnas con el modelo de cajas de Bootstrap. En la columna de la izquierda colocamos un <strong>Textarea <\/strong>para ir agregando y mostrando los mensajes que se reciben del servidor, el <strong>ID <\/strong>del textarea es <strong>mensajes<\/strong>.<\/p>\n\n\n\n<p>En la columna del lado derecho colocamos un <strong>formulario <\/strong>con un campo de texto y un bot\u00f3n. El <strong>ID <\/strong>del campo de texto es <strong>texto<\/strong> y en el se escribir\u00e1n los mensajes que se env\u00edan al servidor. Para ello el formulario invocar\u00e1 la funci\u00f3n enviarTexto() al momento de realizar la acci\u00f3n submit dando click en el bot\u00f3n, el cual de inicio se encuentra deshabilitado.<\/p>\n\n\n\n<p>La siguiente <strong>imagen <\/strong>muestra el despliegue del archivo<strong> index.html<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"379\" src=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba-1024x379.png\" alt=\"\" class=\"wp-image-1725\" srcset=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba-1024x379.png 1024w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba-300x111.png 300w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba-768x284.png 768w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba-16x6.png 16w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba-162x60.png 162w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/03\/Pantalla_prueba.png 1272w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>El siguiente paso ahora es crear el archivo de Javascript, que en este caso se llama <strong>funciones.js<\/strong> y se encuentra dentro de la carpeta<strong> js<\/strong>.<\/p>\n\n\n\n<p>En el archivo funciones.js se crean las funciones enviarTexto(), init(), wsConnect(), onOpen(), onClose(), onMessage(), onError() y doSend()<\/p>\n\n\n\n<p>Al terminar de cargar la ventana se ejecuta la funci\u00f3n init() la cual invoca la conexi\u00f3n con servidor, si en alg\u00fan momento se desconecta, la funci\u00f3n onClose realiza el reintento de conexi\u00f3n cada 2 segundos. Si la conexi\u00f3n tiene \u00e9xito se habilita el bot\u00f3n.<\/p>\n\n\n\n<p>archivo: funciones.js<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>\/\/ Se invoca cuando se oprime el bot\u00f3n Enviar\nfunction enviarTexto(event){\n    event.preventDefault();\n    var campo = event.target.texto;\n    \/\/ Enviamos el valor del campo al servidor\n    doSend(campo.value);\n    \/\/ Vaciamos el campo\n    campo.value=\"\";\n}\n\n\/\/ La funci\u00f3n init se ejecuta cuando termina de cargarse la p\u00e1gina\nfunction init() {\n    \/\/ Conexi\u00f3n con el servidor de websocket\n    wsConnect();\n}\n\n\/\/ Invoca esta funci\u00f3n para conectar con el servidor de WebSocket\nfunction wsConnect() {\n    \/\/ Connect to WebSocket server\n    websocket = new WebSocket(\"ws:\/\/localhost:3000\");\n\n    \/\/ Asignaci\u00f3n de callbacks\n    websocket.onopen = function (evt) {\n        onOpen(evt)\n    };\n    websocket.onclose = function (evt) {\n        onClose(evt)\n    };\n    websocket.onmessage = function (evt) {\n        onMessage(evt)\n    };\n    websocket.onerror = function (evt) {\n        onError(evt)\n    };\n}\n\n\/\/ Se ejecuta cuando se establece la conexi\u00f3n Websocket con el servidor\nfunction onOpen(evt) {\n    \/\/ Habilitamos el bot\u00f3n Enviar\n    document.getElementById(\"enviar\").disabled = false;\n    \/\/ Enviamos el saludo inicial al servidor\n    doSend(\"Hola\");\n}\n\n\/\/ Se ejecuta cuando la conexi\u00f3n con el servidor se cierra\nfunction onClose(evt) {\n\n    \/\/ Deshabilitamos el boton\n    document.getElementById(\"enviar\").disabled = true;\n\n    \/\/ Intenta reconectarse cada 2 segundos\n    setTimeout(function () {\n        wsConnect()\n    }, 2000);\n}\n\n\/\/ Se invoca cuando se recibe un mensaje del servidor\nfunction onMessage(evt) {\n    \/\/ Agregamos al textarea el mensaje recibido\n    var area = document.getElementById(\"mensajes\")\n    area.innerHTML += evt.data + \"\\n\";\n}\n\n\/\/ Se invoca cuando se presenta un error en el WebSocket\nfunction onError(evt) {\n    console.log(\"ERROR: \" + evt.data);\n}\n\n\/\/ Env\u00eda un mensaje al servidor (y se imprime en la consola)\nfunction doSend(message) {\n    console.log(\"Enviando: \" + message);\n    websocket.send(message);\n}\n\n\n\/\/ Se invoca la funci\u00f3n init cuando la p\u00e1gina termina de cargarse\nwindow.addEventListener(\"load\", init, false);<\/code><\/pre>\n\n\n\n<div style=\"color:#ddd\" class=\"wp-block-genesis-blocks-gb-spacer gb-block-spacer gb-divider-solid gb-divider-size-1\"><hr style=\"height:30px\"\/><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Servidor Websockets<\/h3>\n\n\n\n<p>La implementaci\u00f3n del servidor la hacemos con Node.js para lo cual primero creamos el proyecto y la estructura del mismo, posteriormente instalamos las librer\u00edas requeridas.<\/p>\n\n\n\n<p>Creamos la carpeta del proyecto y en la ventana de l\u00ednea de comandos, dentro de la carpeta del proyecto, ejecutamos el comando para la creaci\u00f3n de la aplicaci\u00f3n con Node:<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:addlightplain language-addlightplain\"><code>npm init -y<\/code><\/pre>\n\n\n\n<p>Una vez terminada la ejecuci\u00f3n del init, creamos la carpeta <strong>src <\/strong>y dentro de ella la carpeta <strong>public <\/strong>y el archivo <strong>index.js<\/strong><\/p>\n\n\n\n<p>Posteriormente, instalamos las librer\u00edas que vamos a requerir:<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:addlightplain language-addlightplain\"><code>npm install express cors websockets<\/code><\/pre>\n\n\n\n<p>Para el proyecto, instalamos express y cors para crear el servidor http y para el servidor de Websockets, instalamos la librer\u00eda websockets. Puedes consultar la documentaci\u00f3n adicional de la librer\u00eda websockets en este enlace: <a href=\"https:\/\/github.com\/theturtle32\/WebSocket-Node\/blob\/HEAD\/docs\/index.md\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/theturtle32\/WebSocket-Node\/blob\/HEAD\/docs\/index.md<\/a><\/p>\n\n\n\n<p>Una vez completada la instalaci\u00f3n de las librer\u00edas, colocamos en la carpeta <strong>public <\/strong>el archivo <strong>index.htm<\/strong>l y la carpeta<strong> js<\/strong> con su correspondiente archivo <strong>funciones.js<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/estructura-proyecto.png\"><img loading=\"lazy\" decoding=\"async\" width=\"254\" height=\"256\" src=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/estructura-proyecto.png\" alt=\"\" class=\"wp-image-1734\" srcset=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/estructura-proyecto.png 254w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/estructura-proyecto-150x150.png 150w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/estructura-proyecto-12x12.png 12w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/estructura-proyecto-60x60.png 60w\" sizes=\"auto, (max-width: 254px) 100vw, 254px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>El archivo <strong>index.js<\/strong> que se encuentra dentro de la carpeta <strong>src<\/strong> tendr\u00e1 lo siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-aphph-prism-block lang:javascript language-javascript\"><code>\/\/ importamos las librer\u00edas requeridas\nconst path = require(\"path\");\nconst express = require('express');\nconst cors = require('cors');\nconst app = express();\nconst server = require('http').Server(app);\nconst WebSocketServer = require(\"websocket\").server;\n\n\/\/ Creamos el servidor de sockets y lo incorporamos al servidor de la aplicaci\u00f3n\nconst wsServer = new WebSocketServer({\n    httpServer: server,\n    autoAcceptConnections: false\n});\n\n\/\/ Especificamos el puerto en una varibale port, incorporamos cors, express \n\/\/ y la ruta a los archivo est\u00e1ticos (la carpeta public)\napp.set(\"port\", 3000);\napp.use(cors());\napp.use(express.json());\napp.use(express.static(path.join(__dirname, \".\/public\")));\n\nfunction originIsAllowed(origin) {\n    \/\/ Para evitar cualquier conexi\u00f3n no permitida, validamos que \n    \/\/ provenga de el cliente adecuado, en este caso del mismo servidor.\n    if(origin === \"http:\/\/localhost:3000\"){\n        return true;\n    }\n    return false;\n}\n\n\/\/ Cuando llega un request por sockets validamos el origen\n\/\/ En caso de origen permitido, recibimos el mensaje y lo mandamos\n\/\/ de regreso al cliente\nwsServer.on(\"request\", (request) =&gt;{\n    if (!originIsAllowed(request.origin)) {\n        \/\/ S\u00f3lo se aceptan request de origenes permitidos\n        request.reject();\n        console.log((new Date()) + ' Conexi\u00f3n del origen ' + request.origin + ' rechazada.');\n        return;\n      }\n    const connection = request.accept(null, request.origin);\n    connection.on(\"message\", (message) =&gt; {\n        console.log(\"Mensaje recibido: \" + message.utf8Data);\n        connection.sendUTF(\"Recibido: \" + message.utf8Data);\n    });\n    connection.on(\"close\", (reasonCode, description) =&gt; {\n        console.log(\"El cliente se desconecto\");\n    });\n});\n\n\n\/\/ Iniciamos el servidor en el puerto establecido por la variable port (3000)\nserver.listen(app.get('port'), () =&gt;{\n    console.log('Servidor iniciado en el puerto: ' + app.get('port'));\n})\n\n<\/code><\/pre>\n\n\n\n<p>Los mensajes por <strong>Websockets <\/strong>que recibe el <strong>servidor<\/strong>, los imprime en <strong>consola <\/strong>y los manda de regreso al <strong>cliente<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion.png\"><img loading=\"lazy\" decoding=\"async\" width=\"890\" height=\"362\" src=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion.png\" alt=\"\" class=\"wp-image-1736\" srcset=\"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion.png 890w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion-300x122.png 300w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion-768x312.png 768w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion-16x7.png 16w, https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/Pantalla-en-accion-148x60.png 148w\" sizes=\"auto, (max-width: 890px) 100vw, 890px\" \/><\/a><\/figure>\n\n\n\n<p>Puedes ver la implementaci\u00f3n de este ejemplo en el <strong><a href=\"https:\/\/youtu.be\/nK418x0ymaw\">siguiente video<\/a><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Websockets con Node.js\" width=\"780\" height=\"439\" src=\"https:\/\/www.youtube.com\/embed\/nK418x0ymaw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>Suscr\u00edbete tambi\u00e9n al canal de <strong><a href=\"https:\/\/youtu.be\/nK418x0ymaw\">Youtube<\/a><\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>WebSocket es un protocolo de comunicaci\u00f3n sobre TCP que utiliza un canal full-duplex entre el servidor y el cliente. Vamos a implementar Websockets con Node.js<\/p>\n","protected":false},"author":2,"featured_media":1746,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[5,48],"tags":[109,115,158,159],"class_list":["post-1676","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","category-programacion-web","tag-javascript","tag-node-js","tag-websockets","tag-websockets-con-node-js"],"aioseo_notices":[],"author_meta":{"display_name":"Jacob Avila Camacho","author_link":"https:\/\/www.jacobsoft.com.mx\/es_mx\/author\/jacob-avila\/"},"featured_img":"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/destacada-blog-websockets-300x169.png","featured_image_src":"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/destacada-blog-websockets.png","featured_image_src_square":"https:\/\/www.jacobsoft.com.mx\/wp-content\/uploads\/2021\/04\/destacada-blog-websockets.png","author_info":{"display_name":"Jacob Avila Camacho","author_link":"https:\/\/www.jacobsoft.com.mx\/es_mx\/author\/jacob-avila\/"},"coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/www.jacobsoft.com.mx\/es_mx\/category\/programacion-web\/javascript\/\" class=\"advgb-post-tax-term\">Javascript<\/a>","<a href=\"https:\/\/www.jacobsoft.com.mx\/es_mx\/category\/programacion-web\/\" class=\"advgb-post-tax-term\">Programaci\u00f3n Web<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">Javascript<\/span>","<span class=\"advgb-post-tax-term\">Programaci\u00f3n Web<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/www.jacobsoft.com.mx\/es_mx\/category\/programacion-web\/\" class=\"advgb-post-tax-term\">javascript<\/a>","<a href=\"https:\/\/www.jacobsoft.com.mx\/es_mx\/category\/programacion-web\/\" class=\"advgb-post-tax-term\">node.js<\/a>","<a href=\"https:\/\/www.jacobsoft.com.mx\/es_mx\/category\/programacion-web\/\" class=\"advgb-post-tax-term\">Websockets<\/a>","<a href=\"https:\/\/www.jacobsoft.com.mx\/es_mx\/category\/programacion-web\/\" class=\"advgb-post-tax-term\">websockets con Node.js<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">javascript<\/span>","<span class=\"advgb-post-tax-term\">node.js<\/span>","<span class=\"advgb-post-tax-term\">Websockets<\/span>","<span class=\"advgb-post-tax-term\">websockets con Node.js<\/span>"]}},"comment_count":"8","relative_dates":{"created":"Publicado 5 a\u00f1os hace","modified":"Actualizado 1 a\u00f1o hace"},"absolute_dates":{"created":"Publicado el abril 1, 2021","modified":"Actualizado el febrero 20, 2025"},"absolute_dates_time":{"created":"Publicado el abril 1, 2021 12:20 am","modified":"Actualizado el febrero 20, 2025 1:37 pm"},"featured_img_caption":"","series_order":"","_links":{"self":[{"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/posts\/1676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/comments?post=1676"}],"version-history":[{"count":61,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/posts\/1676\/revisions"}],"predecessor-version":[{"id":1893,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/posts\/1676\/revisions\/1893"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/media\/1746"}],"wp:attachment":[{"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/media?parent=1676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/categories?post=1676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jacobsoft.com.mx\/es_mx\/wp-json\/wp\/v2\/tags?post=1676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}