Under development — the help is being filled in plugin by plugin.
Help/Plugin reference/callbackudpclient
Plugin reference

callbackudpclient

A callback-driven UDP client.

12 functionsnamespace callbackudpclientsource plugins/callback_udp_client/CallbackUdpClientPlugin.c

Written from a line-by-line source review; every example output is from a real run.

Introduction

The callbackudpclient plugin is the counterpart of callbackudpserver: it opens a UDP-sending endpoint on loopback and works **bidirectionally**. With SendText/SendBlob calls it sends datagrams to a given host:port address, and a concurrent background thread forwards any incoming replies to a script-level callback. So a single plugin serves both request sending and reply receiving — a classic UDP request-response pattern.

Relationship to callbackudpserver and asyncmeta

The two plugins (client and server) share lifecycle and state model. State returns asyncmeta.RouteStateOpen (=1) or RouteStateClosed (=0); StateText is the “open”/“closed” text counterpart. The callback blob layout is identical on both sides: 4 bytes port (LE u32) + 4 bytes hostLen (LE u32) + hostLen bytes host string + payload. A UDP client used together with the server thus reads the same blob format.

Lifecycle in a nutshell

(1) `Open(callbackName, timeoutMs, localPort?)` opens a UDP socket on loopback and starts a background thread for incoming replies. (2) `SendText` or `SendBlob` sends a datagram. (3) If a reply arrives, the background thread forwards it to the callback in a blob with port + hostLen + host + payload. (4) `Close` shuts down the socket and waits for the thread to stop. Meanwhile, the state and diagnostic functions (LocalPort, State, Delivered, Dropped, Info, OpenCount) can be queried any time.

Loading the plugin

plugin "../plugins/print/PrintPlugin";
plugin "../plugins/callback_udp_client/CallbackUdpClientPlugin";

A typical flow — UDP request-response

callback i32 OnReply(ref blob $X)
{
// ... process the reply ...
return(1);
}
i32 main()
{
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
callbackudpclient.SendText($cli, "127.0.0.1", 9999, "PING");
// ... wait (e.g. timer.SleepMs), meanwhile OnReply may fire ...
callbackudpclient.Close($cli);
return(0);
}

What to know about every function (the basics)

  • Open always binds to LOOPBACK (127.0.0.1) — a security default, as on the server side.

  • localPort = 0 lets the OS pick a free port; the actual port is returned by LocalPort.

  • timeout = -1 means infinite wait for callback invocation. With a positive timeoutMs, the background thread DROPS an incoming packet if the callback does not fit in the time limit.

  • SendBlob and SendText return the ACTUALLY sent byte count — for UDP, this is normally exactly the payload size.

  • SendText internally calls SendBlob: it wraps the string as a read-only external blob and sends it.

  • EnableAnsiColors returns 1 on Linux (already supported); on Windows it tries to enable virtual-terminal mode (ENABLE_VIRTUAL_TERMINAL_PROCESSING) — handy for colored logging/diagnostic output.

  • An error (stopping the script) is caused by a wrong argument count or type, an out-of-range port (0..65535) or timeout, an invalid clientId, a host resolution failure, touching an already-closed client, and a socket/thread startup failure.

How to read the signatures

callbackName is the script-level reply callback name. timeoutMs is the maximum wait for callback invocation in milliseconds; -1 = infinite. localPort is the local (client-side) UDP port (0 = OS picks). clientId is the positive id given by Open. host is an IPv4 string or a name-resolvable name (typically “127.0.0.1” in the sandbox). The type after the -> arrow is the return type.

Lifecycle

Opening the client endpoint on a loopback port and closing it. Open starts a background thread for incoming replies; Close waits for its shutdown.

callbackudpclient.Open

callbackudpclient.Open(callbackName, timeoutMs, localPort?) ->
int

Opens a UDP client endpoint on loopback IP and forwards incoming replies to the callback via a background thread.

Parameters
Parameter Type Description
callbackName string The name of the script-level reply callback. Signature: `callback i32 NAME(ref blob $X)`.
timeoutMs int The maximum wait for callback invocation in milliseconds. -1 = infinite; otherwise 0..2147483647.
localPort int Optional local UDP port to bind. 0..65535; 0 lets the OS pick. Default: 0.
Return value

The clientId (positive i64). A bad argument or a bind failure raises a runtime error.

Example
callback i32 OnReply(ref blob $X) { return(1); }
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", ($cli > 0));
Output after running
1
When to use

For opening communication with a UDP service. The 0-localPort is handy in CI/test environments since it does not clash with bound ports. The returned clientId is the input of SendText/SendBlob and every further operation.

callbackudpclient.Close

callbackudpclient.Close(clientId) -> int

Closes the client: stops the background thread, shuts down the socket, and releases resources.

Parameters
Parameter Type Description
clientId int The positive client id from Open.
Return value

1 if the client was open and closed successfully; 0 if it was already closed. An unknown or non-positive clientId raises a runtime error.

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.Close($cli));
Output after running
1
When to use

For a clean client shutdown. Close waits for the background thread to actually stop, so the reply callback will no longer fire afterward.

Sending

Sending datagrams to a host:port address. Both verbs return the actually sent byte count.

callbackudpclient.SendText

callbackudpclient.SendText(clientId, host, port, text) -> int

Sends a text datagram to the given address (host:port). Internally calls SendBlob with the text as a read-only blob.

Parameters
Parameter Type Description
clientId int The client id.
host string The destination IPv4 or name-resolvable host (e.g. “127.0.0.1”).
port int The destination UDP port (1..65535).
text string The text to send (UDP payload bytes).
Return value

The actually sent byte count. A bad argument, an unknown clientId, or a `sendto` failure raises a runtime error.

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.SendText($cli, "127.0.0.1", 9999,
"hello"));
Output after running
5
When to use

For text protocols (e.g. ASCII commands, JSON payloads). The return is usually the text length; if smaller, it's truncation or a network error — worth checking.

callbackudpclient.SendBlob

callbackudpclient.SendBlob(clientId, host, port, blob) -> int

Sends a binary data packet to the given address. Passes the blob's full content to `sendto`.

Parameters
Parameter Type Description
clientId int The client id.
host string The destination IPv4 or name-resolvable host.
port int The destination UDP port (1..65535).
blob blob The binary data to send. The blob's full (Size field) length is sent.
Return value

The actually sent byte count. A bad argument, an unknown clientId, or a `sendto` failure raises a runtime error.

Example
i64 $cli;
blob $b[4];
$b[0] = 65;
$b[1] = 66;
$b[2] = 67;
$b[3] = 68;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.SendBlob($cli, "127.0.0.1", 9999,
$b));
Output after running
4
When to use

For binary protocols (struct.assign-ed packets, length-prefixed messages, frame packets). Struct-shaped blobs can be sent directly if you cared about correct endianness when building the content.

State queries

Inspecting the client's current state: the local (bound) port, and the “open/closed” state in both numeric and textual form.

callbackudpclient.LocalPort

callbackudpclient.LocalPort(clientId) -> int

Returns the client's local (bound) UDP port.

Parameters
Parameter Type Description
clientId int The client id.
Return value

The local port (1..65535).

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", (callbackudpclient.LocalPort($cli) > 0));
Output after running
1
When to use

Particularly useful when you passed localPort=0 to Open (asking for an OS-picked port). You query the returned port number with this so you know which port replies arrive on.

callbackudpclient.State

callbackudpclient.State(clientId) -> int

Returns the client's state using the asyncmeta route-state constants.

Parameters
Parameter Type Description
clientId int The client id.
Return value

asyncmeta.RouteStateOpen (=1) if open; asyncmeta.RouteStateClosed (=0) if closed.

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.State($cli));
Output after running
1
When to use

For programmatic state checking, comparing against asyncmeta.RouteStateOpen. Shared numeric code in the callback_* family — uniform processing.

callbackudpclient.StateText

callbackudpclient.StateText(clientId) -> string

Returns the state in human-readable text.

Parameters
Parameter Type Description
clientId int The client id.
Return value

“open” if open; “closed” if closed.

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%s\n", callbackudpclient.StateText($cli));
Output after running
open
When to use

For logging or UI display. The textual counterpart of State's numeric value.

Diagnostics

Counters for received replies, an aggregated key=value state, a plugin-level OpenCount, and a diag helper for ANSI colors.

callbackudpclient.Delivered

callbackudpclient.Delivered(clientId) -> int

Returns the count of reply packets successfully processed (forwarded to the reply callback) so far.

Parameters
Parameter Type Description
clientId int The client id.
Return value

The number of processed replies.

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.Delivered($cli));
Output after running
0
When to use

For monitoring reply throughput. The difference between start and end values of a period gives the replies handled in it.

callbackudpclient.Dropped

callbackudpclient.Dropped(clientId) -> int

Returns the count of dropped reply packets (due to callback timeout or buffer allocation failure).

Parameters
Parameter Type Description
clientId int The client id.
Return value

The number of dropped replies.

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.Dropped($cli));
Output after running
0
When to use

An early signal if the reply callback does not fit in timeoutMs, or the buffer pool is exhausted. A bigger timeoutMs or a faster callback fixes it.

callbackudpclient.Info

callbackudpclient.Info(clientId) -> string

Returns the client's full key=value diagnostic state as a string.

Parameters
Parameter Type Description
clientId int The client id.
Return value

A space-separated key=value list (id, state, stateCode, callback, timeout, localPort, delivered, dropped).

Example
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%s\n", callbackudpclient.Info($cli));
Output after running
id=1 state=open stateCode=1 callback=OnReply timeout=-1
localPort=<auto> delivered=0 dropped=0
When to use

For detailed diagnostics in a single call. The keys are stable; easy to break down further with str.* operations.

callbackudpclient.OpenCount

callbackudpclient.OpenCount() -> int

Returns the number of currently open UDP clients (plugin-level, global view).

Parameters

This function takes no arguments.

Return value

The number of open clients (0 if none).

Example
printf("%d\n", callbackudpclient.OpenCount());
i64 $cli;
$cli = callbackudpclient.Open("OnReply", -1, 0);
printf("%d\n", callbackudpclient.OpenCount());
callbackudpclient.Close($cli);
printf("%d\n", callbackudpclient.OpenCount());
Output after running
0
1
0
When to use

For resource control and diagnostics: after Close it should return to 0 if everything was properly released. Useful for early detection of resource leaks.

callbackudpclient.EnableAnsiColors

callbackudpclient.EnableAnsiColors() -> int

Enables ANSI tools (colored logging) on the current standard output.

Parameters

This function takes no arguments.

Return value

1 if enabled or already supported (Linux/macOS); 0 if not (e.g. non-console output on Windows).

Example
printf("%d\n", callbackudpclient.EnableAnsiColors());
Output after running
1
When to use

For colored output in logs or diag messages. On Linux/macOS it's natively supported (always 1); on Windows it tries to enable the virtual-terminal mode (ENABLE_VIRTUAL_TERMINAL_PROCESSING).

Practical notes

What the callbackudpclient plugin is good for

  • Sending requests to UDP server(s) on loopback (test environment, mock client, debug tool).

  • Request-reply pattern: after a Send*, the background thread forwards incoming replies to a callback, so the script does not block on the recv.

  • Both text and binary payloads are supported (SendText / SendBlob).

  • Simple telemetry with Delivered/Dropped counters, and a readable Info string for the full state.

Processing the callback blob

The incoming reply blob has the same format as in callbackudpserver: 4 bytes port (LE u32) + 4 bytes hostLen (LE u32) + host string + payload. A struct: `struct UdpPacket packet { i32 port; i32 hostLen; }` — after `$X assign UdpPacket;`, `$X.port` and `$X.hostLen` are directly accessible, while the host string and payload can be read with offset-based blob slicing. The two plugins together build a complete request-response channel.

Timeout strategy

timeoutMs=-1 (infinite) gives the callback the full run — the background thread only resumes recv when the callback returns. For high-throughput flows, a shorter (e.g. 50-200 ms) timeoutMs is recommended: the callback must fit in the time window, or the packet is DROPPED (the Dropped counter goes up). If Dropped grows, either raise timeoutMs or speed up the callback.

Loopback-only binding

The plugin intentionally binds only to loopback (127.0.0.1) — a security default, optimized for sandbox-style, tested use. For sending to the external network (e.g. a service on another host), you will need another tool; this plugin is for local communication. The `host` argument must resolve to a loopback address — “127.0.0.1”, “localhost”, or sandbox loopback aliases all work.

Error handling

A wrong argument count or type, an out-of-range port (0..65535) or timeoutMs, an invalid or closed clientId, a host resolution failure, a failed socket/thread startup, and a `sendto` failure are reported by the runtime as a runtime error, and the script stops. A successful Send* returns the sent byte count (normally exactly the payload size for UDP).

The callbackworker async job runner plugin

Script callbacks scheduled on a background thread, asyncmeta-compatible job list — complete function reference