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:
Metric | Type | Description |
---|---|---|
websocket.messages_sent | Counter (count) | Number of messages sent. |
websocket.messages_received | Counter (count) | Number of messages received. |
websocket.send_rate | Rate (msg/sec) | Rate of websocket messages sent over the time period. |
websocket.receive_rate | Rate (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