Skip to main content
Version: Next

WebSocket

WebSocket source connector

Support Those Engines​

Spark
Flink
SeaTunnel Zeta

Key features​

Description​

Used to read data pushed by a WebSocket server over ws:// or wss://. The connector opens a single connection, optionally sends subscription or authentication messages right after the handshake, and turns every received frame into SeaTunnel rows using the configured schema and format.

Unlike the HTTP source, which polls a request/response endpoint, the WebSocket source is driven by the server: rows are produced whenever the server pushes a frame. Text frames are used as they are, binary frames are decoded as UTF-8.

The connector uses a single split, so source parallelism is fixed at 1.

Data Type Mapping​

When schema is configured, the received message is parsed according to format and each field is converted to the declared SeaTunnel type. For the json format the message is parsed as a JSON object or a JSON array of objects; for the text format the message is split by field_delimiter.

When schema is not configured, the whole message is emitted as one row with a single column:

ColumnSeaTunnel Data type
valueSTRING

Options​

NameTypeRequiredDefaultDescription
urlStringYes-WebSocket server url, must start with ws:// or wss://.
headersMapNo-Headers added to the handshake request, for example Authorization.
open_messagesArrayNo-Messages sent to the server in order right after the handshake succeeds, usually subscription or authentication payloads. They are re-sent on every successful reconnect.
formatStringNojsonData format of the received message, only takes effect when schema is configured. Supported values are json and text.
field_delimiterStringNo,Customize the field delimiter, only takes effect when format is text.
connect_timeout_msIntegerNo12000Timeout in milliseconds of establishing the connection.
ping_interval_msIntegerNo0Interval in milliseconds of the WebSocket ping frame used to keep the connection alive, 0 disables it.
enable_reconnectBooleanNotrueWhether to reconnect automatically after the connection is broken.
max_reconnect_timesIntegerNo3Maximum consecutive reconnect attempts before the task fails.
reconnect_interval_msIntegerNo3000Waiting time in milliseconds before each reconnect attempt.
queue_capacityIntegerNo1024Capacity of the local queue buffering received messages. The receiving thread blocks once the queue is full, which back-pressures the server.
poll_timeout_msIntegerNo1000Maximum time in milliseconds that a single read waits on the local queue when no message is available.
max_recordsLongNo-1Stop reading after this number of rows has been emitted, only takes effect in batch mode. -1 means unlimited.
read_timeout_msIntegerNo-1Stop reading after no message has been received for this many milliseconds, counted from the moment the connection is established, only takes effect in batch mode. -1 means unlimited.
common-optionsNo-Source plugin common parameters, please refer to Source Common Options for details.
tip

A WebSocket server keeps pushing data, so with job.mode = STREAMING the source never finishes on its own. With job.mode = BATCH you MUST configure max_records or read_timeout_ms, otherwise the job would never complete and the connector rejects the configuration.

The connector does not checkpoint a server-side offset, so messages buffered in memory or pushed while the job is down are lost after a restart. Do not use it when replayable or exactly-once reads are required.

How to Create a WebSocket Data Synchronization Jobs​

Streaming Mode​

The following example reads a market-data stream and prints it on the local client. The subscription message is sent as soon as the handshake succeeds:

env {
parallelism = 1
job.mode = "STREAMING"
checkpoint.interval = 10000
}

source {
WebSocket {
url = "wss://example.com/stream"
headers {
Authorization = "Bearer <your-token>"
}
open_messages = [
"""{"op":"subscribe","args":["trade.BTCUSDT"]}"""
]
ping_interval_ms = 20000
format = json
schema = {
fields {
symbol = "STRING"
price = "DOUBLE"
ts = "BIGINT"
}
}
}
}

sink {
Console {
parallelism = 1
}
}

Batch Mode​

In batch mode a stop condition is required. The following example collects 100 rows and then finishes, or gives up earlier if the server pushes nothing for 30 seconds:

env {
parallelism = 1
job.mode = "BATCH"
}

source {
WebSocket {
url = "ws://localhost:8080/events"
max_records = 100
read_timeout_ms = 30000
schema = {
fields {
id = "INT"
name = "STRING"
}
}
}
}

sink {
Console {
parallelism = 1
}
}

Without a Schema​

When schema is omitted, each frame is emitted verbatim in a single value column, which is handy for inspecting an unknown stream:

source {
WebSocket {
url = "ws://localhost:8080/events"
max_records = 10
}
}

FAQ​

Why does my batch job fail to start with a configuration error?​

A WebSocket stream has no natural end, so a batch job needs an explicit stop condition. Configure max_records, read_timeout_ms, or both.

How do I authenticate?​

Either put the credentials in headers so they are sent with the handshake request, or send them as the first entry of open_messages when the server expects an application-level login frame. Credentials are never written to the logs.

Some servers instead expect a token in the query string of url. That works too: every log line and error message keeps the parameter names but hides their values, so a url configured as wss://stream.example.com/ws?streams=btcusdt@trade&token=secret is logged as wss://stream.example.com/ws?streams=***&token=***. The connection itself is still made with the url exactly as configured.

A credential placed in the path rather than the query string cannot be hidden this way, because the path identifies the endpoint. Prefer headers or open_messages for such credentials.

What happens when the connection drops?​

By default the connector reconnects up to max_reconnect_times times, waiting reconnect_interval_ms between attempts, and re-sends open_messages after each successful reconnect. Once the attempts are exhausted, the task fails. Set enable_reconnect = false to fail on the first disconnection.

Can I increase the parallelism?​

No. The source uses a single split bound to one connection, so its parallelism is fixed at 1. Run one job per stream instead.

A single frame contains a JSON array, do I get one row or several?​

One row per array element. With format = json, a frame holding a JSON array is fanned out into one row for each element, and max_records counts the produced rows, not the received frames.

Changelog​

Change Log
ChangeCommitVersion
[Feature][Connector-V2] Add WebSocket source connector-Next