Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Node.js
Code

Cómo hacer una aplicación deportiva en tiempo real usando Node.js

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by RRGG (you can also view the original English article)

Final product image
What You'll Be Creating

En el artículo de hoy voy a demostrar cómo hacer una aplicación web que muestre puntajes de juegos en vivo de la NHL. Los puntajes se actualizarán automáticamente a medida que progresan los juegos.

Este es un artículo muy emocionante para mí, ya que me da la oportunidad de reunir dos de mis pasiones favoritas: desarrollo y deportes.

Las tecnologías que se usarán para crear la aplicación son:

  1. Node.js
  2. Socket.io
  3. MySportsFeed.com

Si no tiene instalado Node.js, visite su página de descarga ahora y configúrelo antes de continuar.

¿Qué es Socket.io?

Socket.io es una tecnología que conecta un cliente a un servidor. En este ejemplo, el cliente es un navegador web y el servidor es la aplicación Node.js. El servidor puede tener múltiples clientes conectados a él en cualquier momento.

Una vez establecida la conexión, el servidor puede enviar mensajes a todos los clientes o a un cliente individual. A cambio, el cliente puede enviar un mensaje al servidor, lo que permite la comunicación bidireccional en tiempo real.

Antes de Socket.io, las aplicaciones web comúnmente usaban AJAX, y tanto el cliente como el servidor se sondeaban buscando eventos. Por ejemplo, cada 10 segundos una llamada AJAX ocurriría para ver si había algún mensaje para manejar.

La búsqueda de mensajes causó una gran cantidad de sobrecarga tanto en el cliente como en el servidor, ya que estaría buscando constantemente mensajes cuando no los había.

Con Socket.io, los mensajes se reciben instantáneamente, sin necesidad de buscar mensajes, lo que reduce la sobrecarga.

Aplicación Sample Socket.io

Antes de consumir los datos deportivos en tiempo real, creemos una aplicación de ejemplo para demostrar cómo funciona Socket.io.

Para comenzar, voy a crear una nueva aplicación Node.js. En una ventana de consola, voy a navegar a C: \ GitHub \ NodeJS, crear una nueva carpeta para mi aplicación y crear una nueva aplicación:

Usé todas las configuraciones predeterminadas.

Debido a que estamos creando una aplicación web, voy a utilizar un paquete de NPM llamado Express para simplificar la configuración. En un símbolo del sistema, instálelo de la siguiente manera: npm install express --save

Y, por supuesto, necesitaremos instalar el paquete Socket.io: npm install socket.io --save

Comencemos por crear el servidor web. Cree un nuevo archivo llamado index.js y coloque el siguiente código dentro de él para crear el servidor web usando Express:

Si no está familiarizado con Express, el ejemplo de código anterior incluye la biblioteca Express y crea un nuevo servidor HTTP. En este ejemplo, el servidor HTTP está escuchando en el puerto 3000, p. http: // localhost: 3000. Se crea una ruta en la raíz del sitio "/". El resultado de la ruta devuelve un archivo HTML: index.html.

Antes de crear el archivo index.html, finalicemos el servidor configurando Socket.io. Agregue lo siguiente a su archivo index.js para crear el servidor Socket:

Similar a Express, el código comienza importando la biblioteca Socket.io. Esto se almacena en una variable llamada io. A continuación, utilizando la variable io, se crea un controlador de eventos con la función on. El evento que se escucha es la conexión. Este evento se invoca cada vez que un cliente se conecta al servidor.

Creemos ahora nuestro cliente muy básico. Crea un nuevo archivo llamado index.html y coloca el siguiente código dentro de:

El código HTML anterior carga el JavaScript del cliente Socket.io e inicializa una conexión con el servidor. Para ver el ejemplo, inicie su aplicación de nodo: node index.js

Luego, en su navegador, navegue a http: // localhost: 3000. Nada aparecerá en la página; sin embargo, si observa la consola donde se está ejecutando la aplicación Node, se registran dos mensajes:

  1. El servidor HTTP se inició en el puerto 3000
  2. Conexión de cliente recibida

Ahora que tenemos una conexión de socket exitosa, pongámosla en práctica. Comencemos enviando un mensaje del servidor al cliente. Luego, cuando el cliente recibe el mensaje, puede enviar una respuesta al servidor.

Veamos el archivo abreviado index.js:

La función io.on anterior se ha actualizado para incluir algunas nuevas líneas de código. El primero, socket.emit, envía el mensaje al cliente. El sendToClient es el nombre del evento. Al nombrar eventos, puede enviar diferentes tipos de mensajes para que el cliente pueda interpretarlos de manera diferente. La segunda adición es socket.on, que también contiene un nombre de evento: receivedFromClient. Esto crea una función que acepta datos del cliente. En este caso, los datos se registran en la ventana de la consola.

Eso completa las enmiendas del lado del servidor; ahora puede enviar y recibir datos de cualquier cliente conectado.

Completemos este ejemplo actualizando el cliente para recibir el evento sendToClient. Cuando recibe el evento, puede responder con el evento receivedFromClient al servidor.

Esto se logra en la parte de JavaScript del HTML, por lo que en el archivo index.html, he actualizado el JavaScript de la siguiente manera:

Usando la variable de socket instanciada, tenemos una lógica muy similar en el servidor con una función socket.on. Para el cliente, está escuchando el evento sendToClient. Tan pronto como el cliente se conecta, el servidor envía este mensaje. Cuando el cliente lo recibe, se registra en la consola en el navegador. El cliente luego usa el mismo socket.emit que el servidor utilizado para enviar el evento original. En este caso, el cliente devuelve el evento receivedFromClient al servidor. Cuando el servidor recibe el mensaje, se registra en la ventana de la consola.

Pruébelo usted mismo. Primero, en una consola, ejecute su aplicación de nodo: node index.js. A continuación, cargue http: // localhost: 3000 en su navegador.

Compruebe la consola del navegador web y debería ver los siguientes datos JSON registrados: {hello: "world"}

Luego, en el símbolo del sistema donde se está ejecutando la aplicación Node, debería ver lo siguiente:

Tanto el cliente como el servidor pueden usar los datos JSON recibidos para realizar tareas específicas. Aprenderemos más sobre eso una vez que nos conectemos a los datos deportivos en tiempo real.

Datos de Deportes

Ahora que dominamos cómo enviar y recibir datos hacia y desde el cliente y el servidor, esto se puede aprovechar para proporcionar actualizaciones en tiempo real. Elegí usar datos deportivos, aunque la misma teoría no se limita a los deportes. Antes de comenzar este proyecto, investigué diferentes datos deportivos. El que decidí, porque ofrecen cuentas de desarrollador gratuitas, fue MySportsFeeds (no estoy afiliado a ellos de ninguna manera). Para acceder a los datos en tiempo real, me registré en una cuenta y luego hice una pequeña donación. Las donaciones comienzan en $ 1 para que los datos se actualicen cada 10 minutos. Esto será bueno para el ejemplo.

Una vez que su cuenta esté configurada, puede continuar configurando el acceso a su API. Para ayudar con esto, voy a usar su paquete de NPM: npm install mysportsfeeds-node --save

Una vez que se haya instalado el paquete, las llamadas de API se pueden realizar de la siguiente manera:

En el ejemplo anterior, asegúrese de reemplazar la llamada a la función de autenticación con su nombre de usuario y contraseña.

El siguiente código ejecuta una llamada API para obtener el marcador NHL para hoy. La variable fordate es lo que especifica hoy. También configuré el valor force a true para que siempre se devuelva una respuesta, incluso cuando los datos no han cambiado.

Con la configuración actual, los resultados de la llamada API se escriben en un archivo de texto. En el ejemplo final, esto será cambiado; sin embargo, para fines de demostración, el archivo de resultados se puede revisar en un editor de texto para comprender el contenido de la respuesta. Los resultados contienen un objeto marcador. Este objeto contiene una matriz llamada gameScore. Este objeto almacena el resultado de cada juego. Cada objeto contiene un objeto infantil llamado juego. Este objeto proporciona la información sobre quién está jugando.

Fuera del objeto del juego, hay un puñado de variables que proporcionan el estado actual del juego. Los datos cambian según el estado del juego. Por ejemplo, cuando el juego no ha comenzado, solo hay unas pocas variables que nos dicen que el juego no está en progreso y no ha comenzado.

Cuando el juego está en progreso, se proporcionan datos adicionales sobre el puntaje, el período de tiempo del juego y el tiempo restante. Veremos esto en acción cuando lleguemos al HTML para mostrar el juego en la siguiente sección.

Actualizaciones en Tiempo Real

Tenemos todas las piezas del rompecabezas, por lo que ahora es el momento de armar el rompecabezas para revelar la imagen final. Actualmente, MySportsFeeds tiene soporte limitado para enviar datos a nosotros, por lo que tendremos que sondear los datos de ellos. Afortunadamente, sabemos que los datos solo cambian una vez cada 10 minutos, por lo que no es necesario que agreguemos información adicional al sondear los cambios con demasiada frecuencia. Una vez que sondeamos sus datos, podemos enviar esas actualizaciones desde el servidor a todos los clientes conectados.

Para realizar el sondeo, usaré la función setInterval de JavaScript para llamar a la API (en mi caso) cada 10 minutos para buscar actualizaciones. Cuando se reciben los datos, se envía un evento a todos los clientes conectados. Cuando los clientes reciban el evento, los puntajes del juego se actualizarán con JavaScript en el navegador web.

También se invocará MySportsFeeds cuando la aplicación Nodo se inicie por primera vez. Esta información se usará para cualquier cliente que se conecte antes del primer intervalo de 10 minutos. Esto se almacena en una variable global. Esta misma variable global se actualiza como parte del sondeo de intervalos. Esto asegurará que cuando cualquier nuevo cliente se conecte después del sondeo, tendrá los datos más recientes.

Para ayudar con la limpieza de algunos códigos en el archivo index.js principal, he creado un nuevo archivo llamado data.js. Este archivo contendrá una función que se exporta (disponible en el archivo index.js) que realiza la llamada anterior a la API de MySportsFeeds. Aquí están los contenidos completos de ese archivo:

Una función getData se exporta y devuelve el resultado de la llamada, que en este caso es una Promesa que se resolverá en la aplicación principal.

Ahora veamos el contenido final del archivo index.js:

Las primeras siete líneas de código anteriores ejemplifican las bibliotecas necesarias y la variable global latestData. La lista final de bibliotecas utilizadas es: Express, Http Server creado con Express, Socket.io y el archivo data.js recién creado.

Con las necesidades atendidas, la aplicación rellena latestData para los clientes que se conectarán cuando el servidor se inicie por primera vez:

Las siguientes líneas configuran una ruta para la página raíz del sitio web (http: // localhost: 3000 /) e inician el servidor HTTP para escuchar en el puerto 3000.

Luego, el Socket.io está configurado para buscar conexiones. Cuando se recibe una nueva conexión, el servidor emite un evento llamado datos con los contenidos de la última variable de latestData.

Y finalmente, el fragmento final de código crea el intervalo de sondeo. Cuando se produce el intervalo, la última variable de latestData se actualiza con los resultados de la llamada API. Estos datos luego emiten el mismo evento de datos para todos los clientes.

Puede observar que cuando el cliente se conecta y se emite un evento, está emitiendo el evento con la variable de socket. Este enfoque enviará el evento solo a ese cliente conectado. Dentro del intervalo, el io global se usa para emitir el evento. Esto enviará el evento a todos los clientes.

Eso completa el servidor. Trabajemos en el front-end del cliente. En un ejemplo anterior, creé un archivo index.html básico que configuraba la conexión del cliente que registraría eventos del servidor y enviaría uno de nuevo. Voy a extender ese archivo para que contenga el ejemplo completo.

Como el servidor nos envía un objeto JSON, voy a usar jQuery y aprovechar una extensión jQuery llamada JsRender. Esta es una biblioteca de plantillas. Me permitirá crear una plantilla con HTML que se usará para mostrar el contenido de cada juego de la NHL de una manera consistente y fácil de usar. En un momento, verás el poder de esta biblioteca. El código final tiene más de 40 líneas de código, por lo que voy a dividirlo en fragmentos más pequeños, y luego mostrar el HTML completo al final.

Esta primera parte crea la plantilla que se usará para mostrar los datos del juego:

La plantilla se define con una etiqueta de script. Contiene el ID de la plantilla y un tipo de script especial llamado text / x-jsrender. La plantilla define un contenedor div para cada juego que contiene un juego de clase para aplicar un estilo básico. Dentro de este div, comienza la creación de plantillas.

En el siguiente div, se muestran el equipo local y el de visitante. Esto se hace concatenando la ciudad y el nombre del equipo del objeto del juego de los datos de MySportsFeed.

{{: game.awayTeam.City}} es cómo defino un objeto que se reemplazará con un valor físico cuando se represente la plantilla. Esta sintaxis está definida por la biblioteca JsRender.

Una vez que se muestran los equipos, el siguiente fragmento de código realiza alguna lógica condicional. Cuando el juego esté unPlayed, se emitirá una cadena para que el juego comience a las {{: game.time}}.

Cuando el juego no se completa, se muestra el puntaje actual: Puntuación actual: {{: awayScore}} - {{: homeScore}}. Y, por último, una pequeña lógica engañosa para identificar en qué período está el juego de hockey o si está en el intermedio.

Si la variable CurrentIntermission se proporciona en los resultados, entonces utilizo una función que definí llamada ordinal_suffix_of, que convertirá el número de período para leer: 1.º (2.º, 3.º, etc.) Intermedio.

Cuando no está en el intermedio, busco el valor actual de Período. Esto también usa el ordinal_suffix_of para mostrar que el juego está en el 1 ° (2 °, 3 °, etc.) periodo.

Debajo de esto, otra función que definí llamada time_left se usa para convertir la cantidad de segundos restantes en la cantidad de minutos y segundos restantes en el período. Por ejemplo: 10:12.

La parte final del código muestra el puntaje final porque sabemos que el juego se ha completado.

Aquí hay un ejemplo de cómo se ve cuando hay una mezcla de juegos terminados, juegos en progreso y juegos que aún no han comenzado (no soy un diseñador muy bueno, por lo que se ve como se esperaría cuando un desarrollador hace su propia interfaz de usuario).

An example of finished games

El siguiente paso es un fragmento de JavaScript que crea el socket, el helper funciones ordinal_suffix_of y time_left, y una variable que hace referencia a la plantilla jQuery creada.

La pieza final de código es el código para recibir el evento socket y render la plantilla:

Tengo un div marcador de posición con la identificación de datos. El resultado de la representación de la plantilla (tmpl.render) escribe el HTML en este contenedor. Lo realmente bueno es que la biblioteca JsRender puede aceptar una matriz de datos, en este caso data.scoreboard.gameScore, que itera a través de cada elemento en la matriz y crea un juego por elemento.

Aquí está el HTML final y JavaScript todos juntos:

Inicie la aplicación Node y vaya a http: // localhost: 3000 para ver los resultados usted mismo.

Cada X minutos, el servidor enviará un evento al cliente. El cliente volverá a dibujar los elementos del juego con los datos actualizados. Por lo tanto, cuando deje el sitio abierto y lo observe periódicamente, verá la actualización de los datos del juego cuando los juegos estén actualmente en progreso.

Conclusión

El producto final usa Socket.io para crear un servidor al que los clientes se conectan. El servidor obtiene datos y los envía al cliente. Cuando el cliente recibe los datos, puede actualizar la pantalla sin problemas. Esto reduce la carga en el servidor porque el cliente solo realiza un trabajo cuando recibe un evento del servidor.

Los enchufes no están limitados a una dirección; el cliente también puede enviar mensajes al servidor. Cuando el servidor recibe el mensaje, puede realizar algún procesamiento.

Las aplicaciones de chat comúnmente funcionarían de esta manera. El servidor recibiría un mensaje del cliente y luego lo transmitiría a todos los clientes conectados para mostrar que alguien había enviado un mensaje nuevo.

Espero que hayas disfrutado este artículo ya que me divertí creando esta aplicación deportiva en tiempo real para uno de mis deportes favoritos.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.