Websockets

title

¿Qué son los Websockets?

Los Websockets son un protocolo de comunicación bidireccional y persistente entre un cliente y un servidor, aunque están basados en el protocolo TCP, el intercambio de la información se realiza de manera asíncrona, lo cual es más parecido a un modelo no orientado a conexión como el protocolo UDP. Los Websockets fueron introducidos como parte de las actualizaciones para HTML 5 y estos pueden utilizar los puertos 80 y 443 para la comunicación segura o no segura:

  1. puerto 80 para ws://
  2. puerto 443 para wss://

La comunicación se inicia por medio de una negociación e intercambio de información que puede ser del tipo HTTP o HTTPS a WS o WSS, la principal diferencia entre HTTP y WS es que al finalizar la transferencia de información entre el cliente y el servidor HTTP cierra la conexión y WS la mantiene abierta para enviar actualizaciones. A continuación un ejemplo de la petición del cliente y la respuesta del servidor:

Ejemplo de la petición HTTP del cliente

GET /chat HTTP/1.1
Host: chatserver.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: c2FtcGxlZGF0YQ==
Sec-WebSocket-Origin: http://chatserver.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Ejemplo de la respuesta HTTP del servidor para cambiar el protocolo a WS

HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: ek8sYU8WRgY4WUU=
Sec-WebSocket-Protocol: chat

¿Para qué sirven los Websockets?

Los Websockets son utilizados primordialmente para la mensajería asíncrona y no hay mejor ejemplo para ello que los chats, aunque tiene múltiples áreas de uso en SPAs (Single-page application). La comunicación vía chat es asíncrona debido a que no sabemos en cuanto tiempo el cliente o servidor va a tardar en responder nuestro mensaje, esto también aplicaría para chatbots, sobre todo si tu intención es realizar la prueba end-to-end. Este tipo de prueba no debe confundirse con las pruebas a los modelos de los chatbots, esas se hacen con ML (Machine Learning). Los Websockets establecen un solo canal o puerto de comunicación para transmitir mensajes o actualizaciones que pueden enviarse indistintamente entre ambos actores en cualquier instante de tiempo, lo cual crea una sensación de comunicación en tiempo real. La comunicación no está abierta indefinidamente, existen un tiempo máximo de espera, si durante este tiempo ya no existen actualizaciones la comunicación es finalizada.

¿Cómo probar los Websockets?

Los Websockets pueden ser probados con JMeter por medio de los aditamentos y tenemos 2 opciones:

Empezaremos con el aditamento de Maciej, el cual me parece un excelente aditamento para realizar las pruebas de carga y estrés, aunque un poco oxidado. Hay algo que debemos tener en cuenta antes de iniciar la prueba, cuando se envían mensajes por el medio es muy posible que la respuesta llegue casi instantáneamente o tarde un poco, incluso podríamos recibir una o dos respuestas en un lapso de tiempo. Esto es debido a que JMeter y su motor esta construido de manera síncrona, por lo cual será muy difícil medir tiempos de respuesta precisos, ahora bien existen otras herramientas que pueden realizar la tarea de una mejor forma, pero eso lo cubriremos en las conclusiones.

Terminología

Server Name or IP: Nombre del servidor o dirección IP del servidor.
Port Number: Número del puerto utilizado, puede ser 80 o 443 dependiendo si es seguro o no.
Connection Timeout: Valor máximo en milisegundos para establecer la conexión.
Response/Read Timeout: Valor máximo en milisegundos para leer o recibir respuesta.
Protocol: Protocolo de comunicación, puede ser WS o WSS.

Maciej's

Implementation: Solo disponible RFC6455(v13) la última versión estándar para el protocolo.
Streaming Connection: Indicador si la conexión es reutilizada o finalizada después de utilizar el canal.
Request Data: Mensajes de texto o binarios que serán enviados al servidor.
Response Pattern: Patrón de respuesta con el cual podríamos dar por concluido el mensaje.
Close Connection Pattern: Patrón de respuesta con el cual podríamos dar por concluida la conexión.
Message Backlog: Define el número máximo de mensajes que se pueden almacenar antes de cerrar el muestreador.

Peter's

WebSocket Open Connection: Abre una conexión WS o WSS.
WebSocket Ping/Pong: Enviar un mensaje para mantener viva la comunicación.
WebSocket request-response Sampler: Enviar o recibir información en texto o binario.
WebSocket Single Write Sampler: Enviar información en texto o binario.
WebSocket Single Read Sampler: Recibir información en texto o binario.
WebSocket Close: Cerrar el canal de comunicación.

Receta de cocina

1.- Instalar el aditamento y reiniciar JMeter

Primero debemos instalar el aditamento de Websockets desarrollado por Maciej Zaleski desde el administrador de aditamentos de JMeter, aunque también está disponible el JAR en su sitio de Github, es preferible utilizar el administrador para instalar las dependencias adecuadas. Una vez instalado el aditamento vamos a reiniciar JMeter y validar que el muestreador de tipo Websocket se encuentre disponible dentro del área de muestreadores.

jmeter-plugin

2.- Configurar

Una vez agregado el muestreador, procederemos a configurar la información necesaria para poder establecer la comunicación, para ello vamos a utilizar el sitio de prueba websocket.org, el cual deberá tener la siguiente información:

Server Name or IP: echo.websocket.org Port Number: 80 Connection Timeout: 500 ms Response Timeout: 2000 ms Protocol: ws
Parameters: encoding=text Request Data Hola

jmeter-websocket-sampler

3.- Probar

Después de haber configurado el muestreador de Websocket, necesitamos probar que este funcione. Necesitamos agregar un receptor de Ver resultados en árbol para ver la respuesta del servidor, el cual es un simple eco local que nos responderá lo mismo que le enviemos. Si no te quedó bien el Script, aquí te dejo una liga con una ejemplo.

jmeter-websocket-response

Receta de cocina 2

1.- Instalar el aditamento y reiniciar JMeter

Instalar el aditamento de Websockets desarrollado por Peter Doornbosch desde el administrador de aditamentos de JMeter, aunque de igual forma está disponible el JAR en su sitio de Bitbucket, es preferible utilizar el administrador para instalar las dependencias adecuadas. Una vez instalado el aditamento vamos a reiniciar JMeter y validar que los muestreadores de tipo Websocket se encuentren disponible dentro del área de muestreadores.

jmeter-sampler2

2.- Configurar

Este aditamento es diferente al anterior, porque se require un conjunto de muestreadores para establecer la comunicación, mantenerla aierta, enviar información y finalmente cerrar el canal. Para iniciar debemos colocando un "WebSocket Open Connection" para iniciar la comunicación con la siguiente información:

Server Name or IP: echo.websocket.org
Port Number: 80
Connection Timeout: 500 ms
Read Timeout: 2000 ms
Protocol: ws

jmeter-websocket-open

Después de configurar el módulo de conexión, debemos utilizar el "WebSocket Single Write Sampler" para enviar información al canal, debemos siempre tener habilitado el usar la conexión existente que es el primer radio botón.

Request Data Hola

jmeter-websocket-write

Acto seguido se debe de agregar el "WebSocket Single Read Sampler" para leer información del canal, de igual forma debemos seleccionar la opción de usar la conexión existente.

jmeter-websocket-read

También debemos agregar el "WebSocket Ping/Pong" para mantener el canal de comunicación abierto, de igual forma debemos seleccionar la opción de usar la conexión existente.

jmeter-websocket-ping

Para finalizar debemos agregar el "WebSocket Close" para cerrar el canal y finalizar la comunicación.

jmeter-websocket-close

3.- Probar

Después de haber configurado el muestreador de Websocket, necesitamos probar que este funcione. Necesitamos agregar un receptor de Ver resultados en arbol para ver la respuesta del servidor, el cual es un simple eco local que nos responderá lo mismo que le enviemos. Si no te quedó bien el Script, aquí te dejo una liga con una ejemplo.

jmeter-websocket-response2

¿JMeter es una buena opción para probar Websockets?

La respuesta no es sencilla, pero yo creo que si tu objetivo es simplemente cargar al sistema con peticiones para medir consumo, JMeter hace el trabajo bastante bien. Si tuvieras que medir tiempos precisos de las respuestas probablemente haga un trabajo bueno si sabemos manejar los patrones para la respuesta o para el cerrado del canal, lo cual también es importante a la hora de optimizar los recursos. En general JMeter es una opción pero dependerá mucho del alcance de la prueba, definitivamente no es el fuerte de JMeter realizar pruebas de Websockets, dado que es una herramienta de corazón síncrono y eso limita un poco su perspectiva.

Conclusión

JMeter es una opción válida para realizar esta tarea, también se pueden hacer correlaciones y enviar tokens de autenticidad por medio del canal. En fin, se pueden transmitir prácticamente cualquier archivo o dato, pues también está soportada la transferencia binaria. Pero de igual forma y como lo he intentado transmitir en mis publicaciones anteriores, JMeter no es la mejor opción para este tipo de pruebas, existen otras herramientas como Gatling, Artillery o K6, que están construidas con motores asíncronos que son mejores para estas tareas. Y también para escalar, dado que al ser asíncrono el envío de peticiones, se pueden enviar muchas más sin mantener hilo esperando la respuesta, pero también esto conlleva a vigilar de cerca los recursos como red o memoria, pues fácilmente podríamos sobrecargar los generadores de carga y este beneficio se puede convertir en un martirio.

Saludos.

-Antonio