Waltham
0.1.0
|
How to use the server API while following the example code
References to functions in server-api-example.c are in square brackets. See Server API for a summary of the available API.
A server needs to create its listening socket for TCP itself [server_listen]. Once it is listening and receives a connection, it shall call wth_accept() to create a wth_connection for the new client
[server_accept_client]. Alternatively, if the server wants to call
accept()
on its own, it can call wth_connection_from_fd() with WTH_CONNECTION_SIDE_SERVER.
The file descriptor of a new wth_connection needs to be polled for events [client_create]. Use wth_connection_get_fd() to fetch the connection file descriptor and add it in your poll set for
POLLIN
. (The example also fetches the wth_display for the connection and sets the implementation, but this should be done by Waltham under the hood.)
The wth_connection file descriptor must be serviced as follows [connection_handle_data]:
POLLERR
and POLLHUP:
the connection has died and all client resources need to be cleaned up.POLLOUT:
The server explicitly polled for POLLOUT
because an earlier call to wth_connection_flush() returned with failure EAGAIN
. Now call wth_connection_flush() again. If it succeeds, stop polling for POLLOUT
. If it fails with EAGAIN
, continue polling for POLLOUT
.POLLIN:
The server must read incoming data into a buffer in wth_connection by calling wth_connection_read(). Once the server is ready to process the read messages, it must call wth_connection_dispatch().The server must implement wthp_registry protocol interface. The callback [display_handle_get_registry] gets called when a client creates a wthp_registry object. The server must send a list of the global interfaces it supports as a response. Global interfaces are the interfaces a client can instantiate with the wthp_registry
bind
request (handled in [registry_handle_bind]). The bind request is the first means for clients to create protocol objects.
If a client causes an error, the server must use wth_object_post_error() to deliver an error event to the client. The server should not destroy the wth_connection immediately however, to allow the TCP connection to be torn down gracefully and leave the TCP TIME_WAIT
state with the client. Only once the connection hangs up, the server must destroy the wth_connection. This is also why EPROTO
from wth_connection_dispatch() should be ignored by servers [connection_handle_data].
The server is reponsible for cleaning up all client resources [client_destroy]. Even though wth_connection keeps track of protocol object IDs and wth_object instances, it does not automatically free them. When everything is freed, the server calls wth_connection_destroy().
Events sent to clients are not guaranteed to be sent out to the network automatically, the server needs to call wth_connection_flush() on each wth_connection explicitly [server_flush_clients]. This is best done in the server main loop just before sleeping on
poll
[mainloop].