La Red de Conocimientos Pedagógicos - Currículum vitae - serie netty: multiusos, utiliza el mismo puerto para ejecutar diferentes protocolos

serie netty: multiusos, utiliza el mismo puerto para ejecutar diferentes protocolos

En el artículo anterior, presentamos el soporte de múltiples servicios diferentes en el mismo programa netty. Su lógica es muy simple, es decir, se inician múltiples subprogramas en un programa principal y cada subprograma pasa por un BootStrap. se utiliza para vincular diferentes puertos, de modo que se pueda acceder a diferentes servicios accediendo a diferentes puertos.

Sin embargo, aunque los puertos múltiples están muy diferenciados, todavía existen muchos inconvenientes al usarlos. Entonces, ¿es posible utilizar un solo puerto para unificar diferentes servicios de protocolo?

Hoy les presentaré cómo usar el mismo puerto para ejecutar diferentes protocolos en netty. Este método se llama unificación de puertos.

Antes de explicar la unificación de puertos personalizada, echemos un vistazo a la unificación de puertos propia de Netty, como SocksPortUnificationServerHandler.

Sabemos que existen tres protocolos SOCKS principales, a saber, SOCKS4, SOCKS4a y SOCKS5. Pertenecen a diferentes versiones del mismo protocolo, por lo que no se deben utilizar puertos diferentes y se deben realizar versiones. el mismo puerto.

Específicamente, SocksPortUnificationServerHandler hereda de ByteToMessageDecoder, lo que significa convertir ByteBuf en el objeto Socks correspondiente.

Entonces, ¿cómo distingue entre diferentes versiones?

En el método de decodificación, se pasa el ByteBuf a decodificar y primero se obtiene su índice de lector:

Sabemos que el primer byte del protocolo SOCKS representa la versión, por lo que Lea el primer byte de ByteBuf como número de versión:

Con el número de versión, puede procesarlo a través de diferentes números de versión. Específicamente, para SOCKS4a, debe agregar Socks4ServerEncoder y Socks4ServerDecoder:

.

Para SOCKS5, es necesario agregar dos codificadores y decodificadores, Socks5ServerEncoder y Socks5InitialRequestDecoder:

De esta manera se completa una unificación de puertos y la idea es pasar el mismo puerto entrante El primer byte de ByteBuf se utiliza para determinar el número de versión de SOCKS correspondiente, a fin de procesar diferentes versiones de SOCKS.

En este ejemplo, crearemos una unificación de puertos personalizada para recibir solicitudes HTTP y gzip.

Antes de eso, echemos un vistazo a las palabras mágicas de los dos protocolos. Es decir, cuando obtenemos un ByteBuf, ¿cómo podemos saber si es un protocolo HTTP o un archivo gzip transferido?

Veamos primero el protocolo HTTP. Aquí utilizamos HTTP1.1 de forma predeterminada. Para el protocolo de solicitud HTTP1.1, el siguiente es un ejemplo:

La primera palabra de HTTP. La solicitud es HTTP El nombre del método de solicitud, específicamente hay ocho métodos, los cuales son:

OPCIONES

Devuelve el método de solicitud HTTP admitido por el servidor para recursos específicos. También puede probar la funcionalidad del servidor enviando una solicitud '*' al servidor web.

HEAD

Pide al servidor una respuesta coherente con la solicitud GET, excepto que no se devolverá el cuerpo de la respuesta. Este método le permite obtener la metainformación contenida en los encabezados de respuesta sin tener que transmitir todo el contenido de la respuesta.

GET

Realiza una solicitud de un recurso específico. Nota: El método GET no debe usarse en operaciones que produzcan "efectos secundarios", como en Aplicaciones Web. Una razón es que las arañas web y similares pueden acceder a GET aleatoriamente.

POST

Envíe datos al recurso especificado para procesar la solicitud (como enviar un formulario o cargar un archivo). Los datos se incluyen en el cuerpo de la solicitud. Las solicitudes POST pueden resultar en la creación de nuevos recursos y/o modificación de recursos existentes.

PUT

Carga el contenido más reciente en la ubicación de recursos especificada.

DELETE

Solicita al servidor que elimine el recurso identificado por el Request-URI.

TRACE

Echo de solicitudes recibidas por el servidor, utilizado principalmente para pruebas o diagnóstico.

CONNECT

El protocolo HTTP/1.1 está reservado para servidores proxy que pueden cambiar la conexión a una canalización.

Entonces, ¿cuántos bytes se necesitan para distinguir estos ocho métodos? Puedes ver que un byte no es suficiente, porque tenemos POST y PUT, y su primer byte es P. Por lo tanto, se deben usar 2 bytes como palabra mágica.

Para el protocolo gzip, también tiene un formato especial. Los primeros 10 bytes de gzip son encabezados, donde el primer byte es 0x1f y el segundo byte es 0x8b.

De esta forma también podemos distinguir el protocolo gzip utilizando dos bytes.

De esta forma surge nuestra lógica de controlador. Primero, saque los primeros dos bytes de byteBuf y luego juzgue para distinguir si es una solicitud HTTP o una solicitud gzip:

En consecuencia, también debemos agregarle la codificación y el decodificador correspondientes. Para gzip, netty proporciona ZlibCodecFactory:

Para HTTP, netty también proporciona HttpRequestDecoder, HttpResponseEncoder y HttpContentCompressor para codificar, decodificar y comprimir mensajes HTTP.

Después de agregar el codificador y el decodificador, si desea personalizar algunas operaciones, solo necesita agregar un controlador de mensajes personalizado correspondiente, lo cual es muy conveniente.

Para ver ejemplos en este artículo, consulte: learn-netty4