Mesh Communication Server Relay
This document describes the message routing and propagation logic in the server-to-server relay system used by the DroneEngage Communication Server.
Architecture Overview
┌─────────────────────┐
│ Super Server │
│ (ParentCommServer) │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Child A │ │ Child B │ │ Child C │
│(ChildComm) │ │(ChildComm) │ │(ChildComm) │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
Local Units Local Units Local Units
(WS Clients) (WS Clients) (WS Clients)
Key Components
Files
server/chat_server/js_andruav_chat_server.jsMain local and external message routing logic.
server/server_to_server/js_parent_comm_server.jsSuper server; accepts child communication-server connections.
server/server_to_server/js_child_comm_server.jsChild server; connects to a parent/super communication server.
Core Functions
fn_parseMessage()Location:
js_andruav_chat_server.jsPurpose: Handles messages from local WebSocket clients.
fn_parseExternalMessage()Location:
js_andruav_chat_server.jsPurpose: Handles messages received from relay servers and forwards them further in the relay tree.
forwardMessage()Location:
js_andruav_chat_server.jsPurpose: Forwards local messages to parent or child relay servers.
forwardExternalMessage()Location:
js_andruav_chat_server.jsPurpose: Forwards external relay messages further in the tree with sender exclusion.
getServerOriginID()Location:
js_andruav_chat_server.jsPurpose: Returns the configured
server_idused for loop prevention.
ParentCommServer.forwardMessage()Location:
js_parent_comm_server.jsPurpose: Broadcasts a message to connected child servers, optionally excluding the sender.
ChildCommServer.forwardMessage()Location:
js_child_comm_server.jsPurpose: Sends a message from a child server to its parent server.
Data Flow
1. Local Client to Relay Propagation
When a local WebSocket client sends a message:
Local Client (WebSocket)
│
▼
fn_onWsMessage()
│
▼
fn_parseMessage()
│
├──► Local delivery
│ ├── send_message_toMyGroup()
│ ├── send_message_toMyGroup_GCS()
│ ├── send_message_toMyGroup_Agent()
│ └── send_message_toTarget()
│
└──► forwardMessage()
│
├──► Parent server if enable_super_server=true
└──► Child/parent relay socket if enable_persistant_relay=true
Code path:
fn_onWsMessage()receives the WebSocket message.fn_parseMessage(p_ws, p_message, p_isBinary)parses the message.The server injects the permission field
pfromp_ws.m_loginRequest.m_prm.The message is delivered to local clients according to
tyandtg.forwardMessage()propagates eligible messages to relay servers.
2. External Relay Server to Tree Propagation
When a message arrives from a relay server:
Parent or Child Relay Server
│
▼
fn_parseExternalMessage()
│
├──► Check _origin for loop prevention
│
├──► Local delivery
│ ├── fn_sendToAll()
│ ├── fn_sendToAllGCS()
│ ├── fn_sendToAllAgent()
│ └── fn_sendTIndividualId()
│
└──► forwardExternalMessage()
│
├──► Parent server (grandparent) if enable_persistant_relay=true
└──► Children (excluding sender child) if enable_super_server=true
Code path:
ParentCommServerreceives a child message, orChildCommServerreceives a parent message.The relay wrapper calls
fn_parseExternalMessage(p_message, p_isBinary, p_source_ws).The chat server checks the
_originfield for loop prevention.If the message originated from this server, it is ignored.
Otherwise, the message is delivered to local clients.
forwardExternalMessage()is called to propagate the message further in the relay tree:If in child mode, forwards to parent (grandparent) for upward propagation.
If in parent mode, forwards to children, excluding the source child to prevent sending back to sender.
The
_originfield prevents loops when messages bounce back to their origin server.
Loop Prevention
Server Origin ID
Each communication server should have a unique server_id in server.config. The chat server uses this value as the relay origin ID:
function getServerOriginID() {
return global.m_serverconfig?.m_configuration?.server_id || 'unknown';
}
Origin Injection
forwardMessage() injects _origin before forwarding the message to another server:
if (!v_jmsg._origin) {
v_jmsg._origin = getServerOriginID();
}
This is done only on forwarded messages. Local-only processing does not require _origin.
Origin Check
fn_parseExternalMessage() drops messages that came back to their origin server:
if (v_jmsg._origin === getServerOriginID()) {
return;
}
This prevents a child server from processing its own message when the parent broadcasts it back to all connected children.
Text and Binary Message Handling
The propagation logic supports both text and binary WebSocket messages.
Text Messages
For text messages, the server parses the JSON message, injects or checks fields, and serializes it again when forwarding.
Binary Messages
For binary messages, the message format is:
JSON header + null byte + binary payload
When forwarding binary messages, forwardMessage() parses and modifies only the JSON header. The binary payload is preserved when reconstructing the message.
Routing Types
The ty field determines the message routing behavior:
gConstant:
CONST_WS_MSG_ROUTING_GROUPBehavior: Group broadcast.
iConstant:
CONST_WS_MSG_ROUTING_INDIVIDUALBehavior: Targeted or filtered delivery.
sConstant:
CONST_WS_MSG_ROUTING_SYSTEMBehavior: System command handling; local command path.
Target Field Values
The tg field can contain a specific sender ID or a reserved broadcast target:
_GCS_Constant:
CONST_WS_SENDER_ALL_GCSMeaning: All GCS clients.
_GD_Constant:
CONST_WS_SENDER_ALLMeaning: All units, including GCS and agents.
_AGN_Constant:
CONST_WS_SENDER_ALL_AGENTSMeaning: All drone agents.
Any other non-empty value
Meaning: Specific unit/sender ID.
Local Routing Behavior
For local messages handled by fn_parseMessage():
GCS group messages are delivered to the local group.
Drone group messages are delivered to local GCS clients.
_GCS_targets local GCS clients._GD_targets all local clients._AGN_targets local drone agents.One-to-one messages are first attempted locally; if the target is not found, they are forwarded to relay servers.
System messages are handled by
onSystemMessage()and are not forwarded through the relay path.
External Routing Behavior
For external messages handled by fn_parseExternalMessage():
Group messages are delivered to all local clients and propagated in the relay tree.
_GCS_targets local GCS clients and is propagated in the relay tree._GD_targets all local clients and is propagated in the relay tree._AGN_targets local drone agents and is propagated in the relay tree.No target (default broadcast) targets all local clients and is propagated in the relay tree.
Specific targets (one-to-one messages) are delivered locally if found but are NOT propagated in the relay tree.
Only broadcast messages are re-forwarded to other relay servers to enable tree-like propagation:
Parent mode: Forwards to children, excluding the sender child.
Child mode: Forwards to parent (grandparent) for upward propagation.
Loop prevention via
_originprevents messages from bouncing back to their origin.
Configuration Flags
enable_super_serverEnables parent/super-server mode and allows child communication servers to connect.
enable_persistant_relayEnables child relay mode and connects this server to a parent server.
server_idUnique identifier used in
_originfor loop prevention.
s2s_ws_target_ipParent server address for child relay mode.
s2s_ws_target_portParent server port for child relay mode.
Summary Table
Local WebSocket client
Handler:
fn_parseMessage()Local delivery: Yes
Relay forward: Yes, for eligible messages
Loop handling: Injects
_origininforwardMessage()
Parent relay server
Handler:
fn_parseExternalMessage()Local delivery: Yes
Relay forward: Yes, to children (excluding sender) and to parent (grandparent)
Loop handling: Drops messages whose
_originmatches localserver_id
Child relay server
Handler:
fn_parseExternalMessage()Local delivery: Yes
Relay forward: Yes, to parent (grandparent)
Loop handling: Drops messages whose
_originmatches localserver_id
Validation Notes
This document was reviewed against the current server implementation:
server/chat_server/js_andruav_chat_server.jsserver/server_to_server/js_parent_comm_server.jsserver/server_to_server/js_child_comm_server.js
The documented behavior matches the current implementation:
Local client messages are forwarded to relay servers via
forwardMessage().External relay messages are delivered locally and then re-forwarded via
forwardExternalMessage()to enable tree-like propagation.Parent servers forward to children (excluding the sender child) and to parent (grandparent) if configured.
Child servers forward to parent (grandparent) if configured.
Loop prevention via
_originprevents messages from bouncing back to their origin server.