-
Notifications
You must be signed in to change notification settings - Fork 1
Architecture
FlexComm is built on a modular, event-driven architecture designed to unify multiple communication protocols under a single API and message structure. The architecture is optimized for Unity-based projects and supports high flexibility, runtime configurability, and platform independence.
The FlexClient serves as the central orchestration component in FlexComm. It abstracts the underlying protocols and provides a unified interface for sending, receiving, and routing messages. Designed to be the only component your Unity scripts directly interact with, FlexClient manages all communication lifecycles.
FlexClient maintains active references to one or more protocol implementations that conform to the ICommProtocol interface. It is responsible for initiating connections, monitoring connection state, and dynamically switching between protocols at runtime if needed. It uses asynchronous queues for both outbound and inbound messages, ensuring consistent and performant communication even under high data throughput.
FlexClient also acts as a router. When it receives a FlexMessage, it uses the target field to determine which registered FlexHandlers should process the message. These handlers, attached to GameObjects, implement custom logic without needing to understand the communication layer.
Data Flow: Sending a Message from a Handler
- A FlexHandler (e.g., a StreamHandler) prepares a FlexMessage with the desired payload and metadata.
- The handler calls DispatchMessage(FlexMessage) on the linked FlexClient instance.
- FlexClient places the message into its outgoing queue.
- The message is serialized and forwarded to the currently active ICommProtocol (e.g., TCPManager).
- The protocol manager handles low-level transmission (e.g., chunking, framing, socket dispatch).
- On the receiving end, the protocol deserializes the message and invokes its OnMessageReceived event.
- The receiving FlexClient processes the message, checks the target, and dispatches it to matching FlexHandlers.
This flow highlights the decoupling between user logic, transport mechanism, and routing, which is central to FlexComm's design. Users interact only with FlexClient, abstracting away all protocol complexity.
The FlexMessage class is the cornerstone of FlexComm's abstraction layer. It acts as a transport-agnostic message container, allowing all dataโregardless of communication protocolโto be formatted, routed, and interpreted consistently across the framework. This approach simplifies application logic by decoupling message structure from underlying transport mechanisms.
At its core, a FlexMessage includes:
- Target: A routing identifier that indicates where the message should be delivered. In MQTT, this may map to a topic; in TCP or REST, it helps determine which handler should process the message.
- Payload: A byte array containing the serialized content of the message. This may include plain text, JSON, binary files, or multimedia data.
-
PayloadType: A string descriptor indicating how the payload should be interpreted (e.g.,
utf8,application/json,application/octet-stream). -
Protocol (optional): A string that can be set to identify the sending protocol (e.g.,
MQTT,TCP)โuseful in multi-protocol environments. - SourceClientId (optional): Identifies the client that originated the message, especially useful in systems with multiple senders or brokers.
- Metadata: A container for additional structured fields (e.g., chunk index, filename, total chunks). This is particularly important for file transfer and stream reconstruction.
FlexComm includes static factory methods for generating FlexMessage instances from strings, byte arrays, or serializable Unity objects. These methods simplify the process of preparing outbound messages, while built-in helpers like GetStringPayload() and GetObjectPayload() allow easy decoding on the receiving side.
At its core, a FlexMessage includes:
- Target: A routing identifier that indicates where the message should be delivered. In MQTT, this may map to a topic; in TCP or REST, it helps determine which handler should process the message.
- Payload: A byte array containing the serialized content of the message. This may include plain text, JSON, binary files, or multimedia data.
-
PayloadType: A string descriptor indicating how the payload should be interpreted (e.g.,
utf8,application/json,application/octet-stream). -
Protocol (optional): A string that can be set to identify the sending protocol (e.g.,
MQTT,TCP)โuseful in multi-protocol environments. - SourceClientId (optional): Identifies the client that originated the message, especially useful in systems with multiple senders or brokers.
- Metadata: A container for additional structured fields (e.g., chunk index, filename, total chunks). This is particularly important for file transfer and stream reconstruction.
FlexComm includes static factory methods for generating FlexMessage instances from strings, byte arrays, or serializable Unity objects. These methods simplify the process of preparing outbound messages, while built-in helpers like GetStringPayload() and GetObjectPayload() allow easy decoding on the receiving side.
Use Case Example:
FlexMessage msg = FlexMessage.FromString("Hello world!");
msg.Target = "Logger";
msg.PayloadType = "text/plain";
client.DispatchMessage(msg);Streaming & Chunking Support:
When transferring large payloads like images, audio, or files, FlexMessage supports chunked messaging by including metadata such as filename, index, and total. These fields allow receivers to buffer and reconstruct the original content without additional logic.
Benefits of FlexMessage Design
- Unified message format across all protocols
- Consistent parsing and decoding logic
- Routing-friendly structure for multi-target systems
- Metadata extension without breaking compatibility
By using FlexMessage, FlexComm guarantees interoperability, forward-compatibility, and a clear separation of concerns between transport, routing, and content.
All protocol implementations (MQTT, TCP, UDP, REST, WebSocket, Serial) implement a shared interface:
-
ConnectAsync()/DisconnectAsync() DispatchMessageAsync(FlexMessage)-
Subscribe()/Unsubscribe() -
OnMessageReceivedevent
This allows FlexClient to treat all protocols interchangeably and swap them at runtime.
Handlers are MonoBehaviours that register with FlexClient to receive incoming messages:
-
FlexLogger: Logs messages to console or UI -
StreamHandler: Handles webcam and texture streaming -
FlexFileTransferHandler: Chunked file transfer - Custom handlers can be created for any logic
Handlers are ideal for modularizing application behavior.
Each protocol is encapsulated in its own manager (e.g., MQTTClientManager, TCPManager) and connects to FlexClient via the ICommProtocol interface. The layer includes:
- Persistent connection management
- Topic/port subscription
- Message framing (e.g., TCP length prefixing)
- Platform-specific adaptations (UWP, WebGL)
Message routing is handled by the FlexClient using the target field inside each FlexMessage. This enables:
- Direct addressing of specific handlers or devices
- Multi-client scenarios without data collision
- Rule-based message filtering in handlers
FlexComm is built for full compatibility with:
- โ Windows / macOS / Linux
- โ UWP / HoloLens
- โ WebGL (via NativeWebSocket)
- โ Android / iOS (with protocol caveats)
All protocols are tested across supported platforms with fallbacks where needed (e.g., WebSocket for TCP on WebGL).
FlexComm's architecture centers on abstraction, flexibility, and Unity-native modularity. Users implement only their business logic in FlexHandlers, while all transport, framing, and encoding is handled under the hood by the protocol layer.
FlexClient is your single point of contact for managing all communication across protocols.
This documentation is part of the official FlexComm Wiki.ยฉ 2025 Eagle Creative. All rights reserved.For more information, visit www.eagle-creative.com or reach out at info@eagle-creative.com.