Skip to content

Commit a074774

Browse files
committed
rewrite websocket extensions docs
1 parent 213624f commit a074774

3 files changed

Lines changed: 385 additions & 246 deletions

File tree

docs/03.reference/01.functions/createwebsocketclient/function.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ id: function-createwebsocketclient
44
categories:
55
- protocols
66
related:
7+
- websocket-client-extension
78
- extension-websocket
89
- function-websocketinfo
910
---
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<!--
2+
{
3+
"title": "WebSocket Client Extension",
4+
"id": "websocket-client-extension",
5+
"categories": [
6+
"websocket",
7+
"protocols"
8+
],
9+
"description": "WebSocket client for Lucee — connect to any WebSocket server from CFML",
10+
"keywords": [
11+
"Lucee",
12+
"Extension",
13+
"WebSocket",
14+
"Client"
15+
],
16+
"related": [
17+
"extension-websocket",
18+
"function-createwebsocketclient"
19+
]
20+
}
21+
-->
22+
23+
# WebSocket Client Extension
24+
25+
Provides [[function-CreateWebSocketClient]] for connecting **to** a WebSocket server from Lucee — the opposite direction of the server-side [[extension-websocket]]. Use this for server-to-server communication, integration testing, or consuming external WebSocket APIs from CFML.
26+
27+
**Requires Lucee 6.2+.** Powered by the [nv-websocket-client](https://github.com/TakahikoKawasaki/nv-websocket-client) library.
28+
29+
## Installation
30+
31+
Install via the Lucee Administrator, or see [[extension-installation]] for all options (Dockerfile, deploy, env var, `.CFConfig.json`).
32+
33+
- **Maven GAV:** `org.lucee:websocket-client-extension`
34+
- **Extension ID:** `058215B3-5544-4392-A187A1649EB5CA90`
35+
- **Source:** [github.com/lucee/extension-websocket-client](https://github.com/lucee/extension-websocket-client)
36+
- **Issues:** [Jira — `websockets` label](https://luceeserver.atlassian.net/issues/?jql=labels%20%3D%20%22websockets%22)
37+
- **Downloads:** [download.lucee.org](https://download.lucee.org/#058215B3-5544-4392-A187A1649EB5CA90)
38+
39+
## Usage
40+
41+
Create a listener component to handle WebSocket events:
42+
43+
```lucee
44+
// ClientListener.cfc
45+
component {
46+
47+
variables.messages = [];
48+
49+
function onMessage( message ) {
50+
arrayAppend( variables.messages, message );
51+
}
52+
53+
function onBinaryMessage( binary ) {
54+
// handle binary data
55+
}
56+
57+
function onClose() {
58+
systemOutput( "Connection closed", true );
59+
}
60+
61+
function onError( type, cause, data ) {
62+
systemOutput( "Error [#type#]: #cause.getMessage()#", true );
63+
}
64+
65+
function onPing() {}
66+
67+
function onPong() {}
68+
69+
array function getMessages() {
70+
return variables.messages;
71+
}
72+
73+
}
74+
```
75+
76+
Connect to a WebSocket server:
77+
78+
```lucee
79+
// Create listener and connect
80+
listener = new ClientListener();
81+
ws = CreateWebSocketClient( "ws://localhost/ws/test", listener );
82+
83+
// Send a text message
84+
ws.sendText( "Hello from CFML!" );
85+
86+
// Send binary data — anything that produces a byte[] works
87+
ws.sendBinary( fileReadBinary( "/path/to/payload.bin" ) );
88+
ws.sendBinary( charsetDecode( "raw bytes", "utf-8" ) );
89+
90+
// Check connection status
91+
if ( ws.isOpen() ) {
92+
ws.sendText( "Still connected" );
93+
}
94+
95+
// Close when done
96+
ws.disconnect();
97+
```
98+
99+
Use `wss://` instead of `ws://` to connect over TLS.
100+
101+
### `CreateWebSocketClient()` signature
102+
103+
```text
104+
CreateWebSocketClient( string endpoint, component listener ) -> WebSocket
105+
```
106+
107+
Both arguments are required. The `listener` is a CFC instance whose callbacks (see below) are invoked when messages arrive.
108+
109+
## Listener Callbacks
110+
111+
All callbacks are optional — implement only what you need:
112+
113+
| Callback | Arguments | Description |
114+
|----------|-----------|-------------|
115+
| `onMessage` | `message` | Text message received |
116+
| `onBinaryMessage` | `binary` | Binary data received |
117+
| `onClose` | (none) | Connection closed |
118+
| `onError` | `type, cause, [data]` | Error occurred |
119+
| `onPing` | (none) | Ping frame received |
120+
| `onPong` | (none) | Pong frame received |
121+
122+
Error types: `callback`, `connect`, `general`, `frame`, `message`, `unexpected`.
123+
124+
## WebSocket Object Methods
125+
126+
`CreateWebSocketClient()` returns a Java WebSocket object with these commonly used methods:
127+
128+
```java
129+
sendText( string message ) // send text message
130+
sendBinary( byte[] data ) // send binary data
131+
sendPing() // send ping frame
132+
sendPong() // send pong frame
133+
isOpen() // check if connected
134+
disconnect() // close connection
135+
```
136+
137+
## Notes & Limitations
138+
139+
- **`permessage-deflate` compression is enabled by default** — messages are transparently compressed and decompressed in transit. If you're inspecting frames on the wire, don't expect to see raw text.
140+
- **Connection timeout is hardcoded at 5 seconds** and can't currently be configured. Slow endpoints will fail to connect and throw a `WebSocketException`.
141+
- **No automatic reconnection** — if the connection drops, you're responsible for calling `CreateWebSocketClient()` again. Consider wrapping connect + send in a retry loop with back-off.
142+
- **`onError( type, cause, data )` — the `data` argument is only populated for errors of type `message`** (text-frame decode failures). Every other error type passes `null` for `data`, so your callback should tolerate both 2- and 3-argument invocations.
143+
- **No support for custom connect-time headers or cookies.** If you need to send an `Authorization` header or a session cookie during the handshake, the current BIF doesn't expose that — consider authenticating via query string on the endpoint URL.
144+
- **Sending binary to a Lucee [[extension-websocket]] server endpoint:** the server extension's `@OnMessage` only binds to text frames. `ws.sendBinary()` frames you send to a Lucee-hosted listener are accepted on the wire but won't invoke the listener's `onMessage` callback.

0 commit comments

Comments
 (0)