Cree un sistema de chat utilizando el cable de acción API Rails 5 y ReactJS con múltiples salas privadas y opción de chat grupal

Tenga en cuenta que esta publicación no es un tutorial y requiere el conocimiento de Rails 5 ActionCable y la creación de la biblioteca personalizada ReactJS / Javascript.

Una de las características increíbles que viene con Rails 5 es ActionCable. Con ActionCable, puede crear todas las funciones en tiempo real que se le ocurran a través de websocket. Mientras luchaba por construir un sistema de chat, encontré múltiples ejemplos en la red de cómo construir una aplicación de chat con Rails 5 ActionCable, pero son extremadamente simples incluso para aplicar el concepto para cualquier aplicación de chat de la vida real. Creo que este es el primer ejemplo en Internet que le muestra cómo construir un sistema de chat con:

  • Rails 5 backend API y una interfaz ReactJS
  • Múltiples habitaciones privadas
  • Cualquier número positivo de usuarios en una sala (no solo 1–1) o chat grupal

El sistema de chat que mi talentoso amigo Tim Chang y yo hemos construido tiene:

  1. Múltiples salas de chat privadas
  2. Múltiples usuarios de chat por sala
  3. Estado en línea / fuera de línea de cada usuario
  4. Estado "escribiendo ..." en tiempo real
  5. Recibo de lectura en tiempo real
Así es como se ve nuestro resultado final. (Sin embargo, este artículo de ejemplo no le mostrará el trabajo de front-end)

En esta breve publicación, le mostraré solo lo básico de # 1 y # 2. Déjame un comentario a continuación si quieres que te muestre cómo construir # 3, # 4 y # 5. Estoy usando Rails 5 como la API de back-end y la biblioteca ReactJS en el front-end.

Backend

En la creación, Rails generará las carpetas y archivos de canales donde ocurre toda la magia en tiempo real :)

app / channel / application_cable / channel.rb
aplicación / canales / cable_aplicación / conexión.rb

Autenticación

Primero, autentiquemos las solicitudes de conexión de websocket a su servidor Rails dentro de connection.rb.

Dependiendo de la gema o servicio de autenticación que use en su proyecto, el método find_verified_user debe modificarse según sus necesidades. Tengo un método llamado valid_token? para verificar el token de acceso y el client_id pasado con la solicitud websocket. Si la solicitud no está autenticada, será rechazada.

Estructura de datos

La idea es muy básica: una sala de chat que tiene múltiples mensajes, cada mensaje tiene un contenido y un remitente. Tenga en cuenta que un mensaje no tiene un "receptor". Esto permite que una sala tenga cualquier número de usuarios, ya que no necesita preocuparse por el receptor de los mensajes, ya que todos los mensajes de los remitentes terminarán apareciendo en una sala, independientemente de cuántos participantes haya en la sala. Entonces, esta es la estructura de datos que uso:

  • Conversación (sala): tiene muchos mensajes, usuarios y tiene una identificación
  • Mensaje: pertenece a una conversación, tiene un remitente, tiene el contenido del texto
  • Remitente: es un usuario

Como resultado, creé 3 modelos:

Disparadores de acción

Cuando un cliente se conecta (se suscribe) o transmite un mensaje (hablar), el backend reaccionará con acciones. Dentro de la carpeta aplicación / canales, crearé un archivo llamado room_channel.rb.

Como puede ver en el comentario, después de que un cliente "habla", la transmisión aún no está sucediendo; solo se crea un nuevo mensaje con su contenido y datos. La cadena de acción ocurre después de que el mensaje se guarda en la base de datos. Echemos un vistazo nuevamente en el modelo de mensaje:

after_create_commit {MessageBroadcastJob.perform_later (self)}

Escalabilidad

Esta devolución de llamada se llama solo después de que el Mensaje se crea y se confirma en la base de datos. Estoy usando trabajos en segundo plano para procesar esta acción para escalar. Imagine que tiene miles de clientes enviando mensajes al mismo tiempo (este es un sistema de chat, ¿por qué no?), Aquí se requiere el uso de trabajo en segundo plano.

Aquí es cuando ocurre la transmisión. ActionCable transmitirá la carga útil a la sala especificada con la carga proporcionada.

ActionCable.server.broadcast (room_name, payload)

Ruta del cable

Deberá agregar la ruta / cable websocket a su route.rb para que su cliente pueda llamar a este punto final para transmitir y recibir mensajes.

monte ActionCable.server => '/ cable'

¡Y eso es todo por el lado del backend! Echemos un vistazo a la biblioteca front-end ReactJS.

Biblioteca del cliente

Tenga en cuenta que, según los detalles de su proyecto, deberá comprender el concepto de este código en esta biblioteca y modificarlo según sus necesidades.

Primero, instale ActionCableJS a través de npm.

Cree un archivo ChatConnection.js como uno de los servicios en su aplicación ReactJs.

Así que aquí está el gancho: en createRoomConnection, el cliente intentará conectarse con (suscribirse a) el RoomChannel que creamos en el backend, una vez que esté conectado (suscrito), se transmitirá desde el nombre de la sala ChatRoom-id (mire room_channel. rb arriba otra vez) Una vez que está conectado, hay 2 métodos que se llamarán con frecuencia, ¿puedes adivinar cuál?

Ellos son: recibidos y hablan!

Se llama al método recibido cuando hay un mensaje transmitido al cliente desde el servidor, por el contrario, se llama a hablar cuando el cliente transmite un mensaje al servidor.

Voila! Eso es. Una vez más, esto no está hecho para ser un tipo de tutorial listo para usar porque cada proyecto es diferente, pero espero que te dé una idea de cómo construir un sistema de chat con múltiples salas de chat privadas. y múltiples usuarios por habitación. Por favor, hágamelo saber en la sección de comentarios si tiene alguna pregunta.