Architecture
Overview
Section titled “Overview”TagBites.Net is a TCP client-server library built around three main types:
Client- connects to a singleServerand exchanges messages with it.Server- listens for incoming TCP connections and communicates with any number of connected clients.ServerClient- the server-side representation of a single connected client (returned byServer.GetClients()and passed in server events, e.g.e.Client).
Messages can be plain serializable objects (SendAsync/Received) or, when using RMI, method calls made through generated proxy interfaces (see RMI advanced).
Threading model
Section titled “Threading model”- Setting
server.Listening = truestarts a background thread that accepts incoming connections; it does not block the calling thread. - Each connected client is handled independently, so
Received,ClientConnected, andClientDisconnectedhandlers can be invoked concurrently for different clients. Handlers should be written to be thread-safe if they touch shared state. ClientandServerare thread-safe, but if your handlers mutate shared collections (e.g. a list of clients or a chat history), you are still responsible for synchronizing access to your own state.- All event handlers (
Received,ReceivedError,ClientConnected,ClientDisconnected, etc.) are invoked directly on the background thread-pool thread (Task.Run) that is reading from the socket - there is no marshaling back to a capturedSynchronizationContext. If you update UI (WPF/WinForms) from these handlers, you must dispatch back to the UI thread yourself (e.g.Dispatcher.Invoke/Control.Invoke).
Message flow (plain messages)
Section titled “Message flow (plain messages)”Client.ConnectAsync()opens a TCP connection and (if configured) performs authentication - see Authentication.Client.SendAsync(message)serializes the message using the configuredINetworkSerializer(see Configuration) and writes it to the socket.- On the receiving side, the
Receivedevent fires with the deserialized message. - If deserialization or transport fails,
ReceivedErrorfires instead ofReceived.
Message flow (RMI)
Section titled “Message flow (RMI)”- Both sides register controllers with
Use<TInterface, TImplementation>(). - When one side calls
GetController<TInterface>(), it receives a dynamic proxy implementingTInterface. - Calling a method on the proxy serializes the method name and arguments, sends them to the remote side, invokes the matching method on the registered implementation, and (for non-
voidmethods) sends the return value back. - If no controller was registered ahead of time,
ControllerResolvefires, letting you create and return an instance on demand.
See RMI advanced for exception propagation, async methods, and supported parameter/return types.