Enhance WebSocket support: add opcode handling, binary message support, and improve connection validation
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
:sig
|
||||
WS()
|
||||
|
||||
:desc
|
||||
Defines the WebSocket message handler for the current `.ws.uce` page.
|
||||
|
||||
The same page may expose both `RENDER()` and `WS()`. `RENDER()` serves the initial HTTP response, while `WS()` is called whenever a complete WebSocket message arrives for that page.
|
||||
|
||||
UCE reassembles fragmented messages before calling `WS()`. Text and binary frames are both delivered. Use `ws_opcode()` and `ws_is_binary()` to distinguish them.
|
||||
|
||||
The `call` parameter passed into `WS()` contains:
|
||||
|
||||
- `message`
|
||||
- `connection_id`
|
||||
- `scope`
|
||||
- `opcode`
|
||||
- `document_uri`
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -1,8 +1,9 @@
|
||||
:sig
|
||||
String session_start(String session_name)
|
||||
String session_start(String session_name = "uce-session")
|
||||
|
||||
:params
|
||||
return value : the session ID, defaults to "uce-session"
|
||||
session_name : optional name of the session cookie, defaults to "uce-session"
|
||||
return value : the current session ID
|
||||
|
||||
:desc
|
||||
Starts session or connects to existing session. This function sets a cookie with the name contained in 'session_name' if it does not exist and fills that cookie with a new unique session ID. It then loads the session data for that session ID. Afterwards, the following fields are populated in the 'context' variable:
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
:sig
|
||||
pid_t task_repeat(String key, f64 interval, std::function<void()> exec_func, u64 timeout = 60*10)
|
||||
|
||||
:params
|
||||
key : string uniquely identifying the task
|
||||
interval : repeat interval in seconds
|
||||
exec_func : function to execute repeatedly
|
||||
timeout : optional task timeout value
|
||||
return value : the process ID of the started (or still running) task
|
||||
|
||||
:desc
|
||||
Starts a repeating background worker process. The function `exec_func` is executed in a loop and the worker sleeps for `interval` seconds between executions.
|
||||
|
||||
If a process with the same `key` is already running, `task_repeat()` does not start a second worker and instead returns the PID of the existing one.
|
||||
|
||||
:see
|
||||
>task
|
||||
@@ -0,0 +1,17 @@
|
||||
:sig
|
||||
u64 ws_broadcast(String message, String scope = "")
|
||||
|
||||
:params
|
||||
message : text message to send
|
||||
scope : optional scope identifier, defaults to the current WebSocket page scope
|
||||
return value : number of clients the message was queued for
|
||||
|
||||
:desc
|
||||
Queues a text WebSocket message for every client connected to the given scope and returns the number of recipients.
|
||||
|
||||
If `scope` is omitted, the current page scope is used.
|
||||
|
||||
This helper currently sends text frames only.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,14 @@
|
||||
:sig
|
||||
bool ws_close(String connection_id = "")
|
||||
|
||||
:params
|
||||
connection_id : optional target client ID, defaults to the current WebSocket client
|
||||
return value : true if the target connection exists and was scheduled to close
|
||||
|
||||
:desc
|
||||
Queues a WebSocket close frame and closes the targeted connection.
|
||||
|
||||
If `connection_id` is omitted, the current connection handled by `WS()` is closed.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,14 @@
|
||||
:sig
|
||||
u64 ws_connection_count(String scope = "")
|
||||
|
||||
:params
|
||||
scope : optional scope identifier, defaults to the current WebSocket page scope
|
||||
return value : number of connected WebSocket clients in that scope
|
||||
|
||||
:desc
|
||||
Returns the number of currently connected WebSocket clients for the given scope.
|
||||
|
||||
If `scope` is omitted, the current page scope is used.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,13 @@
|
||||
:sig
|
||||
String ws_connection_id()
|
||||
|
||||
:params
|
||||
return value : connection ID of the current WebSocket client
|
||||
|
||||
:desc
|
||||
Returns the runtime-generated connection ID of the client whose message is currently being handled.
|
||||
|
||||
This ID can be passed to `ws_send_to()` or `ws_close()` to target a single connected client.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,14 @@
|
||||
:sig
|
||||
StringList ws_connections(String scope = "")
|
||||
|
||||
:params
|
||||
scope : optional scope identifier, defaults to the current WebSocket page scope
|
||||
return value : list of connection IDs currently connected to that scope
|
||||
|
||||
:desc
|
||||
Returns the currently connected WebSocket client IDs for the given scope.
|
||||
|
||||
If `scope` is omitted, the current page scope is used.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,13 @@
|
||||
:sig
|
||||
bool ws_is_binary()
|
||||
|
||||
:params
|
||||
return value : true if the current WebSocket message is binary
|
||||
|
||||
:desc
|
||||
Returns whether the message currently being handled by `WS()` arrived as a binary frame.
|
||||
|
||||
If this returns `false`, the current message was delivered as a text frame.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,15 @@
|
||||
:sig
|
||||
String ws_message()
|
||||
|
||||
:params
|
||||
return value : payload of the current WebSocket message
|
||||
|
||||
:desc
|
||||
Returns the payload of the current WebSocket message being handled by `WS()`.
|
||||
|
||||
For text frames this is the decoded text payload. For binary frames this String contains the raw message bytes.
|
||||
|
||||
Use `ws_is_binary()` or `ws_opcode()` to decide how the payload should be interpreted.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,16 @@
|
||||
:sig
|
||||
u8 ws_opcode()
|
||||
|
||||
:params
|
||||
return value : opcode of the current WebSocket message
|
||||
|
||||
:desc
|
||||
Returns the opcode of the message currently being handled by `WS()`.
|
||||
|
||||
Common values are:
|
||||
|
||||
- `0x1` for text messages
|
||||
- `0x2` for binary messages
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,15 @@
|
||||
:sig
|
||||
String ws_scope()
|
||||
|
||||
:params
|
||||
return value : scope identifier of the current WebSocket endpoint
|
||||
|
||||
:desc
|
||||
Returns the runtime's scope identifier for the current WebSocket endpoint.
|
||||
|
||||
This is the same default scope used by `ws_send()`, `ws_broadcast()`, `ws_connections()`, and `ws_connection_count()` when no explicit scope is supplied.
|
||||
|
||||
In the current runtime implementation this scope is the page's internal endpoint identifier, typically the absolute `SCRIPT_FILENAME` of the `.ws.uce` file.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,17 @@
|
||||
:sig
|
||||
bool ws_send(String message, String scope = "")
|
||||
|
||||
:params
|
||||
message : text message to send
|
||||
scope : optional scope identifier, defaults to the current WebSocket page scope
|
||||
return value : true if the message was queued for at least one connected client
|
||||
|
||||
:desc
|
||||
Queues a text WebSocket message for every client connected to the given scope.
|
||||
|
||||
If `scope` is omitted, the current page scope is used.
|
||||
|
||||
This helper currently sends text frames only.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
@@ -0,0 +1,15 @@
|
||||
:sig
|
||||
bool ws_send_to(String connection_id, String message)
|
||||
|
||||
:params
|
||||
connection_id : ID of the target WebSocket client
|
||||
message : text message to send
|
||||
return value : true if the target connection exists and the message was queued
|
||||
|
||||
:desc
|
||||
Queues a text WebSocket message for one specific connected client.
|
||||
|
||||
This helper currently sends text frames only.
|
||||
|
||||
:see
|
||||
>websocket
|
||||
Reference in New Issue
Block a user