Shared AR: how to get data from host when peer hasn't joined yet

Include the following details (edit as applicable):

  • Issue category: Multiplayer
  • Device type & OS version: Android / iOS
  • Host machine & OS version: Windows
  • Issue Environment : Unity Remote / Unity Mock / On Device / Dev Portal
  • ARDK version: 2.3.0

Description of the issue:

So, in a multiplayer session, whenever the host needs to send some message, it will call BroadcastData to send data to all other peers in the networking session. Then, on the other end, the callback OnDidReceiveDataFromPeer will handle the message (in realtime mode).

My (newbie) question is: how do we handle the situation when the peer joins after the host has sent a message that the peer needs to know? For example, how will the peer be notified about, say, the score at that point?

Hi Manos, for asynchronous communication like this the peer will need a way to request this info from the host when they join. Either that or the host will need to poll peers periodically to check if their data is current. Please let me know if this answers your question or if I’m misunderstanding. Thank you!

Hi Bill, thanks for your input. So to describe my case in detail:

  1. The peer joins.
  2. The peer sends a request to host (with just an empty byte because the peer just wants to alert host to send him a string):
internal void AskHostForString (IPeer host) {
  _networking.SendDataToPeer(
          (uint)_MessageType.AskHostMessage,
          new byte[1], // Empty byte
          host,
          TransportType.ReliableUnordered
      );
}
  1. The host ‘catches’ this at the OnDidReceiveDataFromPeer(PeerDataReceivedArgs args)
    and has to Broadcast the string back ?? (this is where it starts to become confusing for me):
 private void OnDidReceiveDataFromPeer(PeerDataReceivedArgs args)
 {
      var data = args.CopyData();
      switch ((_MessageType)args.Tag)
      {
          case _MessageType.AskHostMessage:
              string str = $"MyText";
              byte[] bytes = Encoding.ASCII.GetBytes(str);
              _networking.BroadcastData(
                      (uint)_MessageType.SendPeerMessage,
                      bytes,
                      TransportType.UnreliableUnordered
               );
              break;
       }
      ....
  1. So, now for the peer to receive the string, one more case at the OnDidReceiveDataFromPeer function must be added, the string to be deserialized, and a method to be called with it. Like this:
      ....
       case _MessageType.SendPeerMessage:
              string str = Encoding.ASCII.GetString(data);
              _controller.DoSomethingWithTheString(str);
              break;
       }

Is this the right way to do it?
Or shouldn’t it be so complicated?

I got myself a working version with a somewhat smaller & ‘neater’ logic:

  1. The peer joins.
  2. The host takes notice from the OnPeerAdded event and broadcasts the string to all Peers (but to himself):
void OnPeerAdded(PeerAddedArgs args)
    {
        Debug.LogFormat("Peer joined: {0}", args.Peer.Identifier);
        string str = $"MyText";
        byte[] bytes = Encoding.ASCII.GetBytes(str);
        if (_isHost)
            _networking.BroadcastData(tag: (uint)_MessageType.SendPeerMessage, data: bytes, transportType: TransportType.UnreliableUnordered, sendToSelf: false);
    }
  1. The peer receives the string at the OnDidReceiveDataFromPeer function, deserializes it, and calls the appropriate method. Like this:
....
     case _MessageType.SendPeerMessage:
            string str = Encoding.ASCII.GetString(data);
            _controller.DoSomethingWithTheString(str);
            break;
     }

Case closed. Thanks.

This topic was automatically closed 2 hours after the last reply. New replies are no longer allowed.

Great news Manos! Let me know if anything else comes up