Reference
WebSocket

WebSocket Engine

Enabling WebSocket support

To use the WebSocket engine in an Artillery scenario, set the engine attribute of a scenario definition to ws.

scenarios:
  - name: My WebSocket test
    engine: ws # Enable the Socket.io engine
    flow:
      - send: 'Hello world!'

WebSocket-specific configuration

Subprotocols

WebSocket subprotocols (opens in a new tab) may be configured with config.ws.subprotocols option:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    # Set WebSocket subprotocols:
    subprotocols:
      - json
      - soap

Headers

Connection headers (opens in a new tab) may be specified via the config.ws.headers object.

The following example shows how you can set a custom subprotocol called my-protocol via the Sec-WebSocket-Protocol header (opens in a new tab):

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    # Set a custom WebSocket subprotocol:
    headers:
      Sec-WebSocket-Protocol: my-protocol

Proxies

The config.ws.proxy object is only available in Artillery v2

Proxy settings may be specified via the config.ws.proxy object:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    proxy:
      url: 'https://proxy:port'

Any additional property will be passed to the underlying HTTP(s) proxy agent (opens in a new tab).

Other configuration options

You can configure the underlying WebSocket client via additional objects under config.ws.

For example, to change the number of maximum redirects allowed, use the config.ws.maxRedirects object:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    maxRedirects: 25

For a list of available options, please see WebSocket library docs (opens in a new tab).

Scenario actions and configuration

The WebSocket engine supports five types of actions: connect, send, think, loop, and function.

Configuring the WebSocket connection with connect:

The connect action is only available in Artillery v2

connect must be the first step in the flow and it can be a string, a function or an object.

As a string:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  variables:
    token: 'mytoken'
 
scenarios:
  - engine: ws
    name: Echo a string
    flow:
      - connect: '{{ target }}/?token={{ token }}'
      - send: 'Hello from Artillery'

As a function:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  variables:
    token: 'mytoken'
 
scenarios:
  - engine: ws
    name: Echo a string
    flow:
      - connect:
          function: 'connectHandler'
      - send: 'Hello from Artillery'

The function should have the following signature:

function connectHandler(params, context, next) {
  // This is the same as the "string" example above
  params.target = '${params.target}/?token=${context.vars.token}';
 
  next();
}

Where:

  • params - An object whose properties will be passed to the underlying WebSocket constructor.
  • context - The virtual user's context. context.vars is a dictionary containing all defined variables. context.scenario is the scenario definition for the scenario currently being run by the virtual user.
  • next - The callback which must be called for the scenario to continue. If a value is passed to it, the execution fails.

As an object:

connect accepts all the parameters of the config.ws section plus a target property:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  variables:
    token: 'mytoken'
 
scenarios:
  - engine: ws
    name: Echo a string 1
    flow:
      - connect:
          target: 'ws://echo.websocket.org/?token={{ token }}'
          proxy:
            url: 'http://proxy1:3000'
      - send: 'Hello from Artillery'
  - engine: ws
    name: Echo a string 2
    flow:
      - connect:
          target: '{{ target }}/?token={{ token }}'
          proxy:
            url: 'http://proxy2:3000'
      - send: 'Hello from Artillery, through a different proxy'

Sending data with send

Use send to send data to the server:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    maxRedirects: 25
 
scenarios:
  - engine: ws
    name: Echo a string
    flow:
      - send: 'Hello from Artillery'

If the argument is an object, it will get converted to a string with JSON.stringify (opens in a new tab) before being sent to the target:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: ws
    name: Echo an object
    flow:
      # the following will be stringified and sent as '{"x":5,"y":6}'
      - send:
          x: 5
          y: 6

Pausing execution with think

To pause the virtual user for N seconds, use a think action:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: ws
    flow:
      - send: 'Hello from Artillery'
      - think: 5 # Pause for 5 seconds.
      - send: 'Hello again'

Repeating actions with loop

You can use the loop construct to loop through a number of requests in a scenario.

For example, the following send 100 messages to the target from each virtual user:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: ws
    flow:
      - loop:
          - send: 'Hello from Artillery'
        count: 100

See the Loops section of the Testing HTTP guide for a detailed description of the loop action.

Running custom code with function

A function may be run at any point in a scenario with a function action:

config:
  target: 'wss://echo.websocket.org'
  processor: './my-functions.mjs'
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: ws
    flow:
      - function: 'createTimestampedObject'
      - send: '{{ data }}'

JS functions invoked with the function action have full access to the virtual user's context:

export async function createTimestampedObject(userContext, events) {
  const data = { timestamp: Date.now(), hello: 'world' };
  // set the "data" variable for the virtual user to use in the subsequent action
  userContext.vars.data = data;
}

Examples

Sending data

Send a string to a WebSocket server:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: 'ws'
    flow:
      - send: 'Hello from Artillery'

Send an object to a WebSocket server, which will get automatically converted to a JSON string:

config:
  target: "wss://echo.websocket.org"
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: "ws"
    flow:
      - send:
          id: 1
          name: "Artillery

Use the WAMP (opens in a new tab) and XMPP (opens in a new tab) subprotocols:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    subprotocols:
      - wamp
      - xmpp
 
scenarios:
  - engine: 'ws'
    flow:
      - send: 'Hello from Artillery'

Configure the underlying WebSocket client (opens in a new tab):

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
  ws:
    protocolVersion: 8
    origin: 'https://websocket.org'
    followRedirects: true
    maxPayload: 2048
 
scenarios:
  - engine: 'ws'
    flow:
      - send: 'Hello from Artillery'

Connecting Without Sending Any Data

You can use think to emulate clients connecting to the WebSocket server and listening without sending anything themselves:

config:
  target: 'wss://echo.websocket.org'
  phases:
    - duration: 20
      arrivalRate: 10
 
scenarios:
  - engine: 'ws'
    flow:
      - think: 600 # do nothing for 10m and disconnect

Metrics reported by the engine

In addition to the default metrics reported by Artillery, the Websocket engine reports the following metrics:

MetricTypeDescription
websocket.messages_sentCounter

(count)

Number of messages sent.
websocket.messages_receivedCounter

(count)

Number of messages received.
websocket.send_rateRate

(msg/sec)

Rate of websocket messages sent over the time period.
websocket.receive_rateRate

(msg/sec)

Rate of websocket messages received over the time period.

Debugging

If you're having issues getting your test scenarios to complete successfully, you can print out helpful debugging messages using the DEBUG environment variable.

Print data sent and errors

Set DEBUG=ws when running your tests to view details about the data sent to the WebSocket server and any errors that occurred during the test run.

On macOS and Linux systems, you can temporarily set the DEBUG environment variable by setting its value when running your Artillery test script:

DEBUG=ws artillery run my-script.yaml

For the Windows Command Prompt, you first need to set the DEBUG environment variable using the set command before running the test script:

set DEBUG=ws
artillery run my-script.yaml

If you use PowerShell on Windows, you can set the DEBUG environment variable using $Env:DEBUG before running the test script:

$Env:DEBUG = 'ws'
artillery run my-script.yaml