No results for

Powered byAlgolia

WebSockets

sugerir editar

WebSocket es un protocolo que proporciona canales de comunicación full-duplex a través de una única conexión TCP. Es comúnmente utilizado por las aplicaciones de una sola página (SPA), y en cierta medida por las aplicaciones móviles, para añadir funcionalidad basada en el servidor, lo que suele suponer una mejora del rendimiento respecto a las soluciones basadas en el sondeo.

Pruebas de carga de WebSockets con k6

Comparando las pruebas basadas en HTTP con las de WebSocket, hay algunas diferencias en la estructura y el funcionamiento interno. La principal diferencia es que, en lugar de ejecutar continuamente un bucle de la función principal (export default function() { ... }) una y otra vez, cada VU está ahora configurada para ejecutar un bucle de eventos asíncrono.

La estructura básica de una prueba WebSocket se parece a esto:

Basic structure of WebSocket-based tests
1import ws from 'k6/ws';
2import { check } from 'k6';
3
4export default function () {
5 const url = 'ws://echo.websocket.org';
6 const params = { tags: { my_tag: 'hello' } };
7
8 const res = ws.connect(url, params, function (socket) {
9 socket.on('open', () => console.log('connected'));
10 socket.on('message', (data) => console.log('Message received: ', data));
11 socket.on('close', () => console.log('disconnected'));
12 });
13
14 check(res, { 'status is 101': (r) => r && r.status === 101 });
15}

Como puedes ver arriba el método connect() toma una función "run" como su tercer parámetro, y esa función debe aceptar un objeto Socket como su único parámetro. La función "run" forma la base del bucle de eventos asíncrono.

Será llamada inmediatamente cuando se cree la conexión WebSocket, ejecutará todo el código dentro de ella (normalmente código para configurar los manejadores de eventos), y luego bloqueará hasta que la conexión WebSocket sea cerrada (por el host remoto o usando socket.close()).

Manejo de errores

Para capturar los errores que pueden ocurrir durante la vida de una conexión WebSocket se adjunta un manejador al evento "error", como se ilustra a continuación:

Error handling in WebSocket tests
1 import ws from "k6/ws";
2 import { check } from "k6";
3
4 export default function() {
5 const url = "ws://echo.websocket.org";
6 const params = { "tags": { "my_tag": "hello" } };
7
8 const res = ws.connect(url, params, function(socket) {
9 socket.on('open', function open() {
10 ...
11 });
12
13 socket.on('error', function(e) {
14 if (e.error() != "websocket: close sent") {
15 console.log('An unexpected error occured: ', e.error());
16 }
17 });
18 });
19
20 check(res, { "status is 101": (r) => r && r.status === 101 });
21 }

Timers

Si quieres programar una acción recurrente puedes utilizar la función socket.setInterval para especificar una función que debe ser llamada con un intervalo determinado.

Timers in WebSocket tests
1import ws from 'k6/ws';
2import { check } from 'k6';
3
4export default function () {
5 const url = 'ws://echo.websocket.org';
6 const params = { tags: { my_tag: 'hello' } };
7
8 const res = ws.connect(url, params, function (socket) {
9 socket.on('open', function open() {
10 console.log('connected');
11
12 socket.setInterval(function timeout() {
13 socket.ping();
14 console.log('Pinging every 1sec (setInterval test)');
15 }, 1000);
16 });
17
18 socket.on('ping', () => console.log('PING!'));
19 socket.on('pong', () => console.log('PONG!'));
20 socket.on('close', () => console.log('disconnected'));
21 });
22
23 check(res, { 'status is 101': (r) => r && r.status === 101 });
24}

Timeouts

Se puede añadir un tiempo de espera a la conexión WebSocket pasando una función manejadora así como el valor del tiempo de espera (en milisegundos) a la función socket.setTimeout.

Timeouts in WebSocket tests
1import ws from 'k6/ws';
2import { check } from 'k6';
3
4export default function () {
5 const url = 'ws://echo.websocket.org';
6 const params = { tags: { my_tag: 'hello' } };
7
8 const res = ws.connect(url, params, function (socket) {
9 socket.on('open', () => console.log('connected'));
10 socket.on('close', () => console.log('disconnected'));
11
12 socket.setTimeout(function () {
13 console.log('2 seconds passed, closing the socket');
14 socket.close();
15 }, 2000);
16 });
17
18 check(res, { 'status is 101': (r) => r && r.status === 101 });
19}

El tiempo de espera en el código anterior cerrará la conexión WebSocket después de 2 segundos.

Múltiples manejadores de eventos

Puede adjuntar múltiples funciones de control a un evento, como ilustra el código siguiente.

Multiple event handlers in WebSocket tests
1import ws from 'k6/ws';
2import { check } from 'k6';
3
4export default function () {
5 const url = 'ws://echo.websocket.org';
6 const params = { tags: { my_tag: 'hello' } };
7
8 const response = ws.connect(url, params, function (socket) {
9 socket.on('open', function open() {
10 console.log('connected');
11 socket.send(Date.now());
12
13 socket.setInterval(function timeout() {
14 socket.ping();
15 console.log('Pinging every 1sec (setInterval test)');
16 }, 1000);
17 });
18
19 socket.on('ping', () => console.log('PING!'));
20 socket.on('pong', () => console.log('PONG!'));
21 socket.on('pong', () => {
22 // Multiple event handlers on the same event
23 console.log('OTHER PONG!');
24 });
25
26 socket.on('close', () => console.log('disconnected'));
27
28 socket.on('error', (e) => {
29 if (e.error() != 'websocket: close sent') {
30 console.log('An unexpected error occured: ', e.error());
31 }
32 });
33
34 socket.setTimeout(function () {
35 console.log('2 seconds passed, closing the socket');
36 socket.close();
37 }, 2000);
38 });
39
40 check(response, { 'status is 101': (r) => r && r.status === 101 });
41}