Construya usted mismo un sistema distribuido de mensajería instantánea.
CIM (CROSS-IM) es un sistema de mensajería instantánea para desarrolladores; también proporciona componentes para ayudar a los desarrolladores a construir sus propios sistemas de mensajería instantánea escalables horizontalmente.
A través de CIM, puede lograr los siguientes requisitos:
El siguiente es el diseño arquitectónico específico.
La arquitectura general consta de los siguientes módulos:
servidor cim
servidor de mensajería instantánea; se utiliza para recibir conexiones de clientes, transferencia y mensajes push; , etc.
Soporta implementación de clústeres.
cim-forward-route
Servidor de enrutamiento de mensajes; se utiliza para manejar el enrutamiento de mensajes, el reenvío de mensajes, el inicio de sesión del usuario, el usuario fuera de línea y algunas herramientas operativas (obtener el número de usuarios en línea, etc.). .).
cim-client
Cliente de mensajería instantánea; terminal de mensajería del usuario que se puede iniciar con un solo comando para comunicarse con otros (algunas herramientas de uso común están integradas); comando para facilitar su uso.
El proceso general también es relativamente simple. El diagrama de flujo es el siguiente:
Por lo tanto, cuando nos implementamos, necesitamos los siguientes pasos:
Siguiente. Nos centraremos en implementaciones específicas, como cómo fluyen los chats grupales, los chats privados y los mensajes; cómo registrarse para el descubrimiento de servicios;
Servidor de mensajería instantánea
Primero echemos un vistazo al lado del servidor; implementa principalmente funciones como cliente en línea y fuera de línea, envío de mensajes, etc.
Primero es el inicio del servicio:
Dado que está integrado en SpringBoot, debe iniciar el servicio Netty cuando se inicia la aplicación.
Desde el canal, puede ver que se utiliza el códec Protobuf (los mensajes específicos se analizan en el lado del cliente).
Descubrimiento de registros
El servidor de mensajería instantánea debe cumplir con los requisitos de expansión horizontal, por lo que cim-server debe publicar sus propios datos en el registro.
Por lo tanto, debe registrar sus datos con Zookeeper después de que la aplicación se inicie correctamente.
El objetivo principal es registrar la IP cim-server-port http-port de la aplicación actual.
La imagen de arriba muestra dos instancias de cim-server registradas en mi entorno de demostración (solo los puertos son diferentes ya que están en el mismo servidor).
Esto proporcionará a los clientes (que escuchen este nodo Zookeeper) información en tiempo real sobre los servicios disponibles actualmente.
Iniciar sesión
Después de que el cliente solicite la interfaz de inicio de sesión (ver a continuación) en cim-forward-route para la verificación comercial (al igual que el inicio de sesión diario en otros sitios web), el cliente comenzará con La conexión larga del servidor, como se muestra en el proceso anterior:
En este momento, el cliente enviará un mensaje especial indicando que actualmente está conectado.
Después de recibir esta información, el servidor necesita guardar el ID de usuario del cliente y la relación actual del canal.
También almacena en caché la información del usuario, es decir, ID de usuario y nombre de usuario.
Sin conexión
Cuando el cliente se desconecta, la información almacenada en caché también se borrará.
También debe llamar a la interfaz de enrutamiento para borrar la información (ver más abajo).
Enrutamiento de mensajería instantánea
Como se puede ver en el diagrama de arquitectura, la capa de enrutamiento es muy importante: proporciona una serie de servicios HTTP que conectan clientes y servidores.
Las principales interfaces actuales son las siguientes.
Interfaz de registro
Dado que cada cliente necesita iniciar sesión para usarlo, el primer paso es registrarse.
El diseño aquí es relativamente simple: se utiliza Redis directamente para almacenar la información del usuario; la información del usuario solo tiene ID y nombre de usuario.
Para facilitar la consulta del KV en Redis, este almacena una copia del VK a su vez, por lo que tanto el ID como el nombre de usuario deben ser únicos.
Interfaz de inicio de sesión
El inicio de sesión aquí es diferente del inicio de sesión en cim-server, es de naturaleza comercial.
Para lograr que solo un usuario pueda iniciar sesión, utilizamos una colección en Redis para almacenar la información de inicio de sesión utilizando el ID de usuario como clave; no se escribirán inicios de sesión repetidos.
Obtener instancias de enrutamiento disponibles también es relativamente simple:
Por supuesto, para obtener instancias de servicio en Zookeeper, naturalmente necesita escuchar en el nodo registrado antes de cim-server.
El código es el siguiente:
También escucha el nodo de enrutamiento en Zookeeper después de que se inicia la aplicación y actualiza el caché interno cuando cambia el nodo de enrutamiento.
Interfaz de chat grupal
Esta es la interfaz que realmente envía mensajes. ¡El efecto es que un cliente envía el mensaje y todos los demás clientes reciben el mensaje!
Este proceso es indudable: el cliente envía un mensaje al servidor, el servidor recibe el mensaje, atraviesa todos los canales en el SessionSocketHolder anterior y luego envía el mensaje.
No hay problema si el servidor es independiente, pero este es un diseño de clúster. Por lo tanto, todos los clientes serán asignados a diferentes instancias del servidor cim según el algoritmo de sondeo anterior.
Entonces entra en juego la capa de enrutamiento.
La interfaz de enrutamiento recibe el mensaje y primero atraviesa todas las relaciones de instancia cliente-servidor.
Las relaciones de enrutamiento se almacenan en Redis de la siguiente manera:
Debido a la naturaleza de un solo subproceso de Redis, cuando la cantidad de datos es grande, una vez que se usa la clave para hacer coincidir todos cim-route: * data, hará que Redis no pueda manejar otras solicitudes.
Por lo tanto, utilizamos el comando scan para recorrer todos los datos de cim-route:*.
Luego, la interfaz HTTP para enviar mensajes se llama uno por uno en el servidor donde se encuentra cada cliente.
El proceso de implementación en cim-server es el siguiente:
Cuando cim-server recibe un mensaje, busca el canal para el ID de usuario en la memoria caché interna y envía el mensaje. directamente.
Interfaz de usuario en línea
Esta es una interfaz secundaria para encontrar información sobre los usuarios actualmente en línea.
La implementación también es muy simple, es decir, guardar el "estado de inicio de sesión del usuario para restablecer" antes de realizar la consulta.
Interfaz de chat privado
La razón por la que se dice que adquirir usuarios en línea es una interfaz auxiliar en realidad se utiliza para ayudar en el uso del chat privado.
En general, necesitamos saber quién está en línea para usar el chat privado y luego usted necesita saber con quién desea chatear.
Similar a esto:
En nuestro escenario de aplicación, el requisito previo para el chat privado es que necesita obtener la ID de usuario del usuario en línea.
Por lo tanto, la interfaz de chat privado debe consultar la instancia del servidor cim del destinatario cuando se recibe un mensaje y luego seguir los mismos pasos que un chat grupal. Se llama a la interfaz HTTP de la instancia del destinatario para enviar el mensaje.
La diferencia es que el chat grupal abarcará a todos los usuarios en línea, mientras que el chat privado solo enviará a un usuario.
Interfaz sin conexión
Después de que el cliente se desconecta, debemos eliminar cierta información (información de ruta, estado de inicio de sesión) previamente almacenada en Redis.
Cliente de mensajería instantánea
Parte de la lógica del cliente se ha tratado anteriormente.
Iniciar sesión
El primer paso, iniciar sesión, es llamar a la interfaz de inicio de sesión de enrutamiento al inicio para obtener la información del servidor cim y luego crear una conexión.
Durante el proceso de inicio de sesión, la interfaz de enrutamiento determinará si el inicio de sesión se repite y, de ser así, saldrá del programa.
El siguiente paso es crear una conexión utilizando la información de la instancia del servidor cim (puerto IP) devuelta por la interfaz de enrutamiento.
El último paso es enviar información del indicador de inicio de sesión al servidor para mantener la relación entre el cliente y el canal.
Protocolo personalizado
En nuestro protocolo personalizado, parte de la información de inicio de sesión mencionada anteriormente y la información real son realmente distinguibles.
Dado que esto está codificado y decodificado utilizando los buffers del protocolo de Google, veamos primero el formato sin formato.
De hecho, este acuerdo actualmente abarca tres campos:
Actualmente existen tres tipos principales, correspondientes a diferentes negocios:
Heartbeat
Para mantener la conexión entre el cliente y el servidor, se debe enviar automáticamente un latido cada vez que no se envía un mensaje.
La estrategia actual es enviar un paquete de latido al servidor cada minuto:
De esta manera, el servidor recibirá un paquete de latido cada minuto sin recibir mensajes comerciales, que se utilizan para. ping:
Comandos integrados
El cliente también tiene algunos comandos básicos integrados para facilitar su uso.
Por ejemplo, al escribir :q se saldrá del cliente y se cerrarán algunos recursos del sistema.
Cuando escribes :olo (abreviatura de usuario en línea), se llama a la interfaz "Obtener todos los usuarios en línea" de la ruta.
Chat grupal
El chat grupal es muy fácil de usar, simplemente escribe tu mensaje en la consola y entra.
Esto invocará la interfaz de chat grupal de la ruta.
Chat privado
El chat privado es el mismo, pero la premisa es que debes activar la palabra clave usando el formato userId;; necesita usar: comando olu Permitir que los usuarios estén en línea antes de que puedan usarlo.
Devolución de llamada de mensaje
Para satisfacer ciertas necesidades personalizadas, como mensajes que deben guardarse.
Entonces, después de que el cliente recibe el mensaje, vuelve a llamar a una interfaz donde se puede personalizar el mensaje.
Entonces, primero cree un bean llamador, este bean contiene una interfaz CustomMsgHandleListener, solo necesita implementar esta interfaz si necesita manejarla usted mismo.
Interfaces personalizadas
Como yo no sé mucho sobre cómo escribir interfaces, no puedo decir que otros también lo sepan. Por lo tanto, funciones como chat grupal, chat privado, obtención de usuarios en línea y devolución de llamadas de mensajes en el cliente (y otras) se proporcionan en forma de interfaces.
Esto también facilita la integración de páginas en segundo plano; simplemente llame a estas interfaces; la implementación específica no requiere demasiada atención.
cim es actualmente sólo la primera versión, con más errores y menos funciones (sólo se invita a unos pocos grupos de amigos a probar, sin embargo, se mejorará continuamente en el futuro, al menos esta versión); brinde beneficios a amigos que no tienen experiencia relevante. Obtenga algunas ideas.
Los amigos ingenieros de Java que hayan trabajado durante uno a cinco años pueden unirse al desarrollo de programadores de Java: 721575865
Este grupo proporciona materiales gratuitos de aprendizaje de arquitectura Java (incluida alta disponibilidad y alta concurrencia) , alto rendimiento y distribución, ajuste del rendimiento de Jvm, código fuente Spring, MyBatis, Netty, Redis, Kafka, Myspace, etc.). Materiales arquitectónicos para puntos de conocimiento como Kafka, Mysql, Zookeeper, Tomcat, Docker, Dubbo, Nginx, etc.) Haga un uso razonable de cada minuto y cada segundo de su tiempo para aprender y mejorar, y no use "no lo suficiente". tiempo” para encubrir tu pereza mental! Aquí, nos gustaría recordar a todos los candidatos que durante el proceso de redacción, deben prestar atención a "cada segundo cuenta" y no ocultar su pereza al pensar porque "no hay suficiente tiempo".