> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/grafana/k6/llms.txt
> Use this file to discover all available pages before exploring further.

# k6/websockets

> Modern WebSocket API for k6 load testing

# k6/websockets

The `k6/websockets` module provides a modern, standards-compliant WebSocket API for k6. This is the newer WebSocket implementation that follows the browser WebSocket API more closely.

<Note>
  This module is different from `k6/ws`, which provides the legacy WebSocket API. The `k6/websockets` module offers a more modern, event-driven approach.
</Note>

## WebSocket Class

The main class for creating WebSocket connections.

### Constructor

```javascript theme={null}
import { WebSocket } from 'k6/websockets';

const ws = new WebSocket(url);
const wsWithProtocol = new WebSocket(url, protocols);
```

<ParamField path="url" type="string" required>
  The WebSocket server URL (must start with `ws://` or `wss://`)
</ParamField>

<ParamField path="protocols" type="string | string[]">
  Optional subprotocol(s) to use
</ParamField>

### Properties

<ResponseField name="binaryType" type="string">
  Type of binary data being received. Can be `"blob"` or `"arraybuffer"` (default: `"blob"`)
</ResponseField>

<ResponseField name="bufferedAmount" type="number">
  Number of bytes queued to be sent (read-only)
</ResponseField>

<ResponseField name="extensions" type="string">
  Extensions selected by the server (read-only)
</ResponseField>

<ResponseField name="protocol" type="string">
  Subprotocol selected by the server (read-only)
</ResponseField>

<ResponseField name="readyState" type="number">
  Current connection state:

  * `0` (CONNECTING): Connection not yet established
  * `1` (OPEN): Connection is open and ready to communicate
  * `2` (CLOSING): Connection is in the process of closing
  * `3` (CLOSED): Connection is closed
</ResponseField>

<ResponseField name="url" type="string">
  The WebSocket URL (read-only)
</ResponseField>

### Methods

#### send()

Sends data through the WebSocket connection.

<ParamField path="data" type="string | ArrayBuffer | Blob" required>
  Data to send to the server
</ParamField>

```javascript theme={null}
ws.send("Hello, server!");
ws.send(JSON.stringify({ type: "message", content: "Hello" }));
```

#### close()

Closes the WebSocket connection.

<ParamField path="code" type="number">
  Numeric status code (default: 1000)
</ParamField>

<ParamField path="reason" type="string">
  Human-readable closing reason
</ParamField>

```javascript theme={null}
ws.close();
ws.close(1000, "Normal closure");
```

### Event Handlers

#### addEventListener()

Registers an event listener for WebSocket events.

<ParamField path="event" type="string" required>
  Event type: `"open"`, `"message"`, `"close"`, `"error"`, or `"ping"`/`"pong"`
</ParamField>

<ParamField path="handler" type="function" required>
  Function to call when the event occurs
</ParamField>

```javascript theme={null}
ws.addEventListener('open', () => {
  console.log('Connection opened');
});

ws.addEventListener('message', (event) => {
  console.log('Received:', event.data);
});

ws.addEventListener('close', () => {
  console.log('Connection closed');
});

ws.addEventListener('error', (event) => {
  console.error('WebSocket error:', event.error);
});
```

## Complete Example

Based on the k6 source example:

```javascript theme={null}
import { randomString, randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.1.0/index.js';
import { WebSocket } from 'k6/websockets';

const sessionDuration = randomIntBetween(1000, 3000); // user session between 1s and 3s

export default function () {
  for (let i = 0; i < 4; i++) {
    startWSWorker(i);
  }
}

function startWSWorker(id) {
  // Create a new websocket connection
  const ws = new WebSocket(`wss://quickpizza.grafana.com/ws`);
  ws.binaryType = 'arraybuffer';
  
  ws.addEventListener('open', () => {
    // Change the user name
    ws.send(JSON.stringify({ event: 'SET_NAME', new_name: `VU ${__VU}:${id}` }));
    
    // Listen for messages/errors and log them into console
    ws.addEventListener('message', (e) => {
      const msg = JSON.parse(e.data);
      if (msg.event === 'CHAT_MSG') {
        console.log(`VU ${__VU}:${id} received: ${msg.user} says: ${msg.message}`);
      } else if (msg.event === 'ERROR') {
        console.error(`VU ${__VU}:${id} received:: ${msg.message}`);
      } else {
        console.log(`VU ${__VU}:${id} received unhandled message: ${msg.message}`);
      }
    });
    
    // Send a message every 2-8 seconds
    const intervalId = setInterval(() => {
      ws.send(JSON.stringify({ event: 'SAY', message: `I'm saying ${randomString(5)}` }));
    }, randomIntBetween(2000, 8000)); // say something every 2-8 seconds
    
    // After a sessionDuration stop sending messages and leave the room
    const timeout1id = setTimeout(function () {
      clearInterval(intervalId);
      console.log(`VU ${__VU}:${id}: ${sessionDuration}ms passed, leaving the chat`);
      ws.send(JSON.stringify({ event: 'LEAVE' }));
    }, sessionDuration);
    
    // After a sessionDuration + 3s close the connection
    const timeout2id = setTimeout(function () {
      console.log(`Closing the socket forcefully 3s after graceful LEAVE`);
      ws.close();
    }, sessionDuration + 3000);
    
    // When connection is closing, clean up the previously created timers
    ws.addEventListener('close', () => {
      clearTimeout(timeout1id);
      clearTimeout(timeout2id);
      console.log(`VU ${__VU}:${id}: disconnected`);
    });
  });
}
```

## Event Objects

### MessageEvent

<ResponseField name="data" type="string | ArrayBuffer | Blob">
  The data sent by the server
</ResponseField>

<ResponseField name="origin" type="string">
  The origin of the WebSocket server
</ResponseField>

### CloseEvent

<ResponseField name="code" type="number">
  The close code sent by the server
</ResponseField>

<ResponseField name="reason" type="string">
  The reason for closing
</ResponseField>

<ResponseField name="wasClean" type="boolean">
  Whether the connection closed cleanly
</ResponseField>

## Key Differences from k6/ws

<CardGroup cols={2}>
  <Card title="k6/websockets" icon="star">
    * Event-driven API
    * Multiple event listeners
    * Standards-compliant
    * Modern browser-like API
  </Card>

  <Card title="k6/ws" icon="clock">
    * Callback-based API
    * Single handler per event
    * Legacy implementation
    * Simpler for basic use cases
  </Card>
</CardGroup>

## Use Cases

* Real-time chat applications
* Live notifications and updates
* Multiplayer games
* Financial tickers and dashboards
* IoT device communication

## Related Resources

* [k6/ws (Legacy API)](/javascript-api/k6-ws)
* [WebSocket Protocol Testing](/protocols/websockets)
* [Timers Module](/javascript-api/k6-timers)
