That's what I refer to as "unpacking/packing" in my original post. It's inelegant for a number of reasons especially if you want to preserve a "is host/peer agnostic" type of architecture in the code.
In order to address the problem, I had to create a top-level function called "CustomSendMessage" which takes three parameters:
There is a special global tag I created called "RELAY_MESSAGE" which I will reference later.
Let me outline the function's logic branches for you:
- Function is being called by the host: no wrapping is necessary, use Multiplayer Send Message normally.
- Function is being called by a client but the destination is the host: Again no wrapping is necessary, use Multiplayer Send Message normally.
- Function is being called by a client and destination is a client:
Send a message to the host with Tag (RELAY_MESSAGE), message is modified to be: DestId & "|" & OriginalTag & "|" & OriginalMessage
Now we need a Host-only Multiplayer On Message RELAY_MESSAGE received logical trigger:
- Unpacks the modified message, prepares to send a normal message to the true peer DestId with OriginalTag
- The modified message becomes: Multiplayer.FromID & "|" & OriginalMessage
Whenever a client receives any message, they have to determine if the true sender was the HOST or a relayed client which is done through a custom function called:
GetTrueSender (string Message) - Returns Multiplayer.FromID or a token if the true source peer id was packed into the message.
It works and solves the problem since the messages in my app are fairly infrequent, otherwise this solution might possibly introduce some latency in a different type of app.
Either way, I'm still having to write a bit of kludge in that I'm adding a potentially unnecessary man-in-the-middle if it is actually possible to send direct messages peer-to-peer. However, this may be a limitation of WebRTC (all messages have to be sent to the peer-to-host-to-peer), I haven't done enough research.