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

callbackudpserver

A callback-driven UDP server.

9 functionsnamespace callbackudpserversource plugins/callback_udp_server/CallbackUdpServerPlugin.c

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

Introduction

The callbackudpserver plugin provides a minimal UDP server pattern: it opens a loopback port, and forwards incoming packets to a script-level callback. The server is driven by a background thread that watches for packets between `recvfrom` blockings; every packet reaches the given callback as a “borrowed” blob containing the sender's port, the IP host string, and the payload together. The callback may return a response blob, which the plugin immediately sends back to the sender — so a request-response pattern is supported.

Relationship to asyncmeta

The plugin uses the already documented asyncmeta constants: the State function returns asyncmeta.RouteStateOpen (=1) or RouteStateClosed (=0). StateText is the textual counterpart of the state (“open” or “closed”). This way the callback families use a uniform, shared vocabulary for the state.

Callback blob layout

For every incoming packet, the background thread invokes a script-level callback. The callback signature is `callback i32 NAME(ref blob $X)`. The borrowed blob has the following little-endian layout: 4 bytes port (sender's port), 4 bytes hostLen (host string length), then hostLen bytes of host string (usually “127.0.0.1”), and finally the actual payload (the remaining bytes). With the struct.assign pattern it is easy to process: define a struct with port + hostLen on the surface, and read the fields from it.

Loading the plugin

plugin "../plugins/print/PrintPlugin";
plugin "../plugins/callback_udp_server/CallbackUdpServerPlugin";

A typical flow — UDP echo server

callback i32 OnPacket(ref blob $X)
{
// Send the incoming packet's echo back (ref blob → response).
return(1);
}
i32 main()
{
i64 $sid;
$sid = callbackudpserver.Open("OnPacket", -1, 0);
// ... the background thread runs, callbacks fire ...
callbackudpserver.Close($sid);
return(0);
}

What to know about every function (the basics)

  • Open always listens on LOOPBACK (localhost). It is NOT bound to an external IP.

  • port = 0 lets the OS pick a port; the actual port is returned by Port.

  • timeout = -1 means infinite wait for the callback; a positive value (ms) is the maximum wait after which the packet is DROPPED (Dropped counter goes up).

  • State returns RouteStateOpen (=1) or RouteStateClosed (=0); same constants as in asyncmeta.

  • serverId is a positive, monotonically increasing integer (i64); every subsequent operation (Close, Port, State, …) expects it.

  • The background thread stops on Close (the socket shutdown breaks the recvfrom), and only then does Close return.

  • OpenCount returns the number of currently open servers globally at the plugin level (regardless of which server they belong to).

  • 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 serverId, and a socket/thread startup failure.

How to read the signatures

callbackName is the script-level callback name. timeoutMs is the maximum wait for callback invocation in milliseconds; -1 = infinite. port is the TCP/IP UDP port (0..65535; 0 = OS picks). serverId is the positive id given by Open, expected by every subsequent operation. The type after the -> arrow is the return type.

Lifecycle

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

callbackudpserver.Open

callbackudpserver.Open(callbackName, timeoutMs, port?) -> int

Opens a UDP server on loopback IP and forwards incoming packets to the callback through a background thread.

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

The serverId (positive i64), expected by other operations. A bad argument or a bind failure raises a runtime error.

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

For starting a tested UDP service (debug server, local echo, mock microservice). The 0-port is particularly handy in CI/test environments, because it does not clash with already-bound ports.

callbackudpserver.Close

callbackudpserver.Close(serverId) -> int

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

Parameters
Parameter Type Description
serverId int The positive server id from Open.
Return value

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

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

For a clean server shutdown. Close waits for the background thread to actually stop, so the callback will no longer fire afterward — you can safely release resources tied to the callback.

State queries

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

callbackudpserver.Port

callbackudpserver.Port(serverId) -> int

Returns the server's actual bound port.

Parameters
Parameter Type Description
serverId int The server id.
Return value

The port (1..65535).

Example
i64 $sid;
$sid = callbackudpserver.Open("OnPacket", -1, 0);
printf("%d\n", (callbackudpserver.Port($sid) > 0));
Output after running
1
When to use

Particularly useful when you passed port=0 to Open (asking for an OS-picked port). You query the returned port number with this — and you can advertise it to clients.

callbackudpserver.State

callbackudpserver.State(serverId) -> int

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

Parameters
Parameter Type Description
serverId int The server id.
Return value

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

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

For programmatic state checking: comparing with asyncmeta.RouteStateOpen tells whether the server is alive. Same numeric code as the other callback_* plugins.

callbackudpserver.StateText

callbackudpserver.StateText(serverId) -> string

Returns the state in human-readable text.

Parameters
Parameter Type Description
serverId int The server id.
Return value

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

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

For logging or UI display. The textual counterpart of State's numeric value — same information in readable form.

Diagnostics

Counters and a key=value info string about the server's activity; a plugin-level OpenCount for the global view.

callbackudpserver.Handled

callbackudpserver.Handled(serverId) -> int

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

Parameters
Parameter Type Description
serverId int The server id.
Return value

The number of processed packets.

Example
i64 $sid;
$sid = callbackudpserver.Open("OnPacket", -1, 0);
printf("%d\n", callbackudpserver.Handled($sid));
Output after running
0
When to use

For monitoring server throughput. Worth recording at the start of a given test or period, and observing the difference at the end — that gives the count of packets handled in that period.

callbackudpserver.Dropped

callbackudpserver.Dropped(serverId) -> int

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

Parameters
Parameter Type Description
serverId int The server id.
Return value

The number of dropped packets.

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

For an early signal of performance degradation: if it grows, either the callback does not fit in timeoutMs, or the buffer pool ran out. Raise timeoutMs, or write the callback faster.

callbackudpserver.Info

callbackudpserver.Info(serverId) -> string

Returns the server's complete key=value diagnostic state as a string.

Parameters
Parameter Type Description
serverId int The server id.
Return value

A space-separated key=value list. Fields: id, state, stateCode, callback, timeout, port, handled, dropped.

Example
i64 $sid;
$sid = callbackudpserver.Open("OnPacket", -1, 0);
printf("%s\n", callbackudpserver.Info($sid));
Output after running
id=1 state=open stateCode=1 callback=OnPacket timeout=-1
port=<auto> handled=0 dropped=0
When to use

For detailed diagnostics in a single call. The keys are stable; easy to parse (str.Find, str.Split-like patterns). Ideal for logging or a developer interface.

callbackudpserver.OpenCount

callbackudpserver.OpenCount() -> int

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

Parameters

This function takes no arguments.

Return value

The number of open servers (0 if none).

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

For resource control and diagnostics. After Close it should return to 0; if it does not, that is a resource leak. For monitoring the real active count when managing multiple servers in parallel.

Practical notes

What the callbackudpserver plugin is good for

  • Starting a tested UDP service on loopback (debug server, local echo, mock).

  • Event-driven packet processing: every incoming datagram is a callback invocation; the script can focus on the content.

  • Request-response pattern: the callback's return blob is automatically sent back to the sender.

  • Simple telemetry: the Handled/Dropped counters give a snapshot of the server's state.

Processing the callback blob

The blob is little-endian: the first 4 bytes are the sender port (uint32), the next 4 bytes are the host string length (uint32), then the host string (usually “127.0.0.1”), and finally the payload. It can be declared as a struct: `struct UdpPacket packet { i32 port; i32 hostLen; }` — after `$X assign UdpPacket;`, `$X.port` and `$X.hostLen` are directly accessible. The host string and the payload can be read further via offset-based blob slicing.

Timeout and the Dropped counter

The timeoutMs parameter gives the callback's maximum wait time. If the callback takes longer (e.g. slow I/O), the background thread DROPS the packet and increments the Dropped counter. timeoutMs=-1 (infinite) is the most forgiving, but you may lose high-throughput capability, because the background thread only resumes receiving once the callback returns. For high traffic, a short (e.g. 50-200 ms) timeoutMs is recommended — a rising Dropped warns when intervention is needed.

Loopback-only binding

The plugin intentionally binds only to loopback (127.0.0.1) — a security default, optimized for sandbox-style, tested use. You CANNOT start a server reachable from the external network with this plugin; for that, the callback_listener or another suitable plugin (with the proper configuration) is the tool.

Error handling

An invalid argument (wrong type, empty callback name, port > 65535, timeout > INT_MAX, negative timeout != -1), a failed socket creation, a port conflict on bind, a failed background-thread start, and a call referring to an already-closed server are reported by the runtime as a runtime error, and the script stops. Close signals an open server with 1 and an already-closed one with 0 — but both are successful call results (not a runtime error).

The callbackudpclient UDP client plugin

Loopback UDP client, datagram sending, and reply callback — complete function reference