Skip to content

WebSocket

Qriist edited this page Sep 17, 2026 · 3 revisions

LibQurl provides direct support for the WebSocket protocol over an easy handle. The workflow requires explicitly converting the connection to a WebSocket after establishing it.

Converting to WebSocket

WebSocketConvert upgrades the existing easy_handle connection to a WebSocket handshake. It handles the TCP/TLS setup, HTTP upgrade exchange, and internal framing configuration automatically:

curl.SetOpt("URL", "wss://ws.example.com/socket", easy_handle)
curl.WebSocketConvert(easy_handle)

After this call, the handle enters WebSocket mode. Sync() is no longer used for the main transfer lifecycle; use WebSocketSend and WebSocketReceive instead.

Sending Data

WebSocketSend transmits a message over the open connection:

curl.WebSocketSend("hello")

Accepts all common AHKv2 sources. Objects, Maps, and Arrays are automatically JSON-dumped before transmission.

Receiving Data

WebSocketReceive reads incoming frames from the server:

curl.WebSocketReceive()

For text-based WebSocket endpoints, GetLastBody() can be called immediately after to retrieve the decoded string:

curl.WebSocketReceive(easy_handle)
response := curl.GetLastBody(, easy_handle)

Frame Configuration

Outgoing frames are automatically split at 10 KB by default. This can be adjusted for larger payloads:

curl.SetWebSocketFrameSize(20 * 1024) ; Split frames at 20 KB

Typical Lifecycle

#Include <LibQurl>

curl := LibQurl()

; Prepare payload
payload := FileOpen("data.txt", "r").Read()

; Configure and upgrade to WebSocket
curl.SetOpt("URL", "wss://ws.postman-echo.com/raw")
curl.WebSocketConvert()

; Exchange data
curl.WebSocketSend(payload)
curl.WebSocketReceive()

; Retrieve response
responseBody := curl.GetLastBody()
MsgBox responseBody

Ignored Return Code: 81 (CURL_WAITING_READY)

WebSocketReceive internally polls the underlying socket until data arrives. During this polling loop, libcurl may return CURLCode 81 to indicate the socket is not yet ready for reading (a non-blocking timeout). Rather than exposing this as an error or forcing you to manually poll, LibQurl catches it, sleeps 50 milliseconds, and retries internally.

This happens transparently in normal operation, meaning you will typically never see 81 in caughtErrors or in the return code. Only actual transfer errors (non-81 non-zero codes) bubble up to you most of the time.

However, enabling debug mode will allow 81 to push an error capture into caughtErrors. Since every transfer is dozens of loops, be prepared for a significant volume of error objects indicating this particular healthy code.

Notes

  • The easy handle remains in WebSocket mode until explicitly cleaned up or the script exits. Calling Sync() again while in WebSocket mode may fail or produce unexpected results.
  • See Raw Send and Receive for lower-level TCP/SSL transport.
  • See Easy Handle Reference — full method list

Clone this wiki locally