plesty.lib.service.tcp_ip_client
ZeroMQ-based TCP/IP client for remote device control.
Attributes
Classes
ZeroMQ-based client for remote device control. |
Module Contents
- plesty.lib.service.tcp_ip_client.DISCONNECT_TIMEOUT_S = 30.0
- class plesty.lib.service.tcp_ip_client.DeviceTCPIPClient(address='tcp://localhost:5555', timeout=5000, resources=None, client_id: str | None = None, connect_kwargs: dict | None = None)
ZeroMQ-based client for remote device control.
This client provides a transparent interface to a remote device server. Methods can be invoked as if the device were local.
The server address it was opened with stays available as
address.- Features:
Standard query/write interface
Arbitrary remote function calls
Automatic method discovery and binding
Timeout support
Structured error handling
Initialize the device client.
- Parameters:
address – Server address.
timeout – Receive timeout in milliseconds.
resources – Resource request as a string, flat collection, or nested dict tree.
client_id (str | None) – Optional stable client identity for server-side routing.
connect_kwargs (dict | None) – Optional metadata sent during connect handshake.
- ctx
- socket
- client_id = 'client-00000000000000000000000000000000'
- address = 'tcp://localhost:5555'
- resources
- connect_kwargs
- default_timeout = 5000
- response_grace_ms = 1000
- _connected = False
- connection_info = None
- _budgets: dict[str, float]
- set_default_timeout(timeout_ms: int) None
Change the receive timeout used by requests without their own.
- Parameters:
timeout_ms (int) – New default receive timeout in milliseconds.
- Return type:
None
- connect() None
Connect to the server, discover methods, and bind them locally.
- Return type:
None
- _close_socket() None
Close the socket and context without waiting for undelivered messages.
The handshake to an absent server sits in the DEALER’s queue forever; with the default infinite LINGER,
ctx.term()then blocks forever too — a connect to a dead server never returned, and no deadline could bound it. Linger 0 drops what could not be delivered.- Return type:
None
- _send(payload)
Send a request to the server and wait for response.
- Parameters:
payload – Dictionary payload.
- Returns:
Result from server.
- Return type:
Any
- Raises:
RuntimeError – If server returns an error.
TimeoutError – If no response is received.
- connect_to_server() Any
Send a handshake so the server can register client metadata.
- Return type:
Any
- disconnect_from_server() Any
Release server-side allocations, and wait for the server to confirm.
Given its own generous window rather than the client default: the device runs calls on one thread, so a disconnect arriving behind a long operation waits for that operation first. On the client default it timed out, the socket closed, and the server’s confirmation went nowhere — leaving the allocations held and the log unable to distinguish a clean exit from a client that vanished.
- Raises:
TimeoutError – If the server does not confirm in time. The client is marked disconnected either way; the caller decides whether to care, and
close()logs and carries on.- Return type:
Any
- _resolve_recv_timeout_ms(payload_timeout_s)
Convert per-request operation timeout (seconds) into socket receive timeout (ms).
A small grace window is added so the client still receives timeout/error responses sent by the server right after operation timeout is reached.
- query(param: Any, timeout: Any = None) Any
Query a device parameter.
- Parameters:
param (Any) – Parameter name.
timeout (Any) – Optional timeout in seconds (server-side).
- Returns:
Parameter value.
- Return type:
Any
- write(param: Any, value: Any, timeout: Any = None) Any
Write a device parameter.
- Parameters:
param (Any) – Parameter name.
value (Any) – Value to set.
timeout (Any) – Optional timeout in seconds (server-side).
- Returns:
Result from device.
- Return type:
Any
- call(func: Any, *args: Any, timeout: Any = None, **kwargs: Any) Any
Call a remote device function.
An operation that declared a budget through
describeis waited for that long unless the caller passes atimeoutof its own. This is where the budget is applied rather than in the bound proxy, because this is the one funnel every call goes through: anything invoking an operation by name — the client field test, a caller working from a method list — never touches the proxy, and applying it there only left those on the client default.- Parameters:
func (Any) – Function name.
args (Any) – Positional arguments.
timeout (Any) – Optional timeout in seconds (server-side). Overrides the operation’s declared budget.
kwargs (Any) – Keyword arguments.
- Returns:
Function result.
- Return type:
Any
- describe() dict[str, Any]
Retrieve available device methods from server.
- Returns:
Device description.
- Return type:
dict
- close() None
Release server-side allocations, then close local ZMQ resources.
The socket is not torn down until the server has confirmed the disconnect, or until
DISCONNECT_TIMEOUT_Shas passed with no answer. Closing first leaves the server holding this client’s allocations and writing its reply to an identity that no longer exists — the “answer lost, the operation still ran” case, which looks in the log exactly like a client that crashed.The wait is bounded rather than open-ended: a server that has died will never answer, and close() must still return.
- Return type:
None
- __enter__()
Enter the client context manager.
- __exit__(exc_type, exc_value, traceback)
Exit the client context manager, closing the connection.
- _build_methods()
Dynamically attach remote methods as local methods.