Search Unity

5.2 vs 5.1: Discrepency in message handling

Discussion in 'Multiplayer' started by Iron-Warrior, Oct 26, 2015.

  1. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    Hi, I made this thread a couple of days ago (not required reading for this one, however), and upon further investigating the issue I found that 5.1 and 5.2 seem to handle messaging over Unet differently. I'd normally file a bug report, but I'm not sure which one is actually the intended behavior. Either way, for my purposes I need to know exactly how the messaging system in the HLAPI works and I'm having trouble figuring it out. Anyways. I noticed when building my project in 5.2 my messages seemed to be all arriving at the exact same time. To test this theory, I wrote this script:

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using System.Collections;
    4. using UnityEngine.Networking.NetworkSystem;
    5.  
    6. public class NetTest : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     bool printSender = true;
    10.  
    11.     [SerializeField]
    12.     bool printReceiver = true;
    13.  
    14.     NetworkClient client;
    15.  
    16.     private int i = 0;
    17.  
    18.     void InitializeClient()
    19.     {
    20.         client = new NetworkClient();
    21.  
    22.         client.Connect(inputHost, 7777);
    23.         client.RegisterHandler(MsgType.Highest + 1, GetMsg);
    24.     }
    25.  
    26.     void GetMsg(NetworkMessage netMsg)
    27.     {
    28.         if (printReceiver)
    29.         {
    30.             var msg = netMsg.ReadMessage<IntegerMessage>();
    31.             Debug.Log(string.Format("Receiver: {0} - {1}", msg.value, Time.time));
    32.         }
    33.     }
    34.  
    35.     void Update()
    36.     {
    37.         if (NetworkServer.connections.Count > 0)
    38.         {
    39.             i++;
    40.  
    41.             if (printSender)
    42.                 Debug.Log(string.Format("Sender: {0} - {1}", i, Time.time));
    43.  
    44.             NetworkServer.SendUnreliableToAll(MsgType.Highest + 1, new IntegerMessage(i));
    45.         }
    46.     }
    47.  
    48.     void InitializeServer()
    49.     {
    50.         NetworkServer.Listen(7777);
    51.         NetworkServer.RegisterHandler(MsgType.Connect, OnServerConnect);
    52.     }
    53.  
    54.     void OnServerConnect(NetworkMessage netMsg)
    55.     {
    56.         NetworkServer.SetClientReady(netMsg.conn);
    57.     }
    58.  
    59.     string inputHost = "localhost";
    60.  
    61.     void OnGUI()
    62.     {
    63.         if (!NetworkServer.active)
    64.         {
    65.             if (GUI.Button(new Rect(400, 20, 200, 20), "Init Server"))
    66.             {
    67.                 InitializeServer();
    68.             }
    69.         }
    70.  
    71.         if (client == null || !client.isConnected)
    72.         {
    73.             if (GUI.Button(new Rect(100, 20, 200, 20), "Client Connect"))
    74.             {
    75.                 InitializeClient();
    76.             }
    77.  
    78.             inputHost = GUI.TextField(new Rect(100, 60, 200, 20), inputHost);
    79.         }
    80.     }
    81. }
    This sends a message every frame to all clients with a message index. The time the message is sent is logged, and the time it's received is logged. I was running both the client and server in the same Unity instance (but not as a local host). On 5.2 I get this:

    Unity52Test.png

    So you can see that the sender sends a bunch of messages, once per frame, as it should. Then the receiver gets a group of about 6 messages all in one frame (this was the source of my original frustration, as I was writing a custom network transform that obviously needs to transfer it's messages as quickly as possible).

    I didn't recall having this behavior in 5.1, so I downloaded 5.1.2f1, built a new project and did the same thing as before. I got this:

    Unity51Test.png

    This time things are different. The sender still works the same, but the receiver seems to be getting messages more randomly. Sometimes in single messages, sometimes in groups of 2 or 3. Either way, something has very clearly changed.

    My 5.2 version is the latest (5.2.2f1). Both ran at the same framerate (about 70), and both are identical projects (I upgraded the new 5.1 project to 5.2 after I reinstalled 5.2 to test it). My questions about this are:

    • When does Unet actually "send" the messages you ask it to through the various Send methods? Does it buffer a bunch of them beforehand? Is the size of this buffer exposed anywhere? Can I override this and tell Unet to send it as quickly as possible?
    • When does Unet actually process all the messages through the handlers? Before Update? After? I'm assuming when it receives a bunch of messages in between Update calls it stores them somewhere and then processes them all at once (running the method handling the message multiple times in correct order)
    I dug around the docs and didn't find anything, but Unet is still fairly new (and searches still return plenty of results about the Legacy Networking), so I might have missed something.

    Thanks for any answers,
    Erik
     
  2. irwiss

    irwiss

    Joined:
    Apr 14, 2015
    Posts:
    7
    Not sure if it was changed 5.1->5.2 but you could look into NetworkConnection.SetMaxDelay
     
  3. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    Bang on, that was exactly it. I'm guessing this post by @seanr answers the mystery of the 5.1->5.2, as I'm considering if this bug was fixed there was probably a default value put in.

    In addition, if I switch the QoS to StateUpdate (from Unreliable), all of the messages get sent and then received in turn in individual update frames, which is exactly what I wanted. In Unreliable for some reason often 2-3 messages will be received in the same Update frame...which sort of makes sense, given that StateUpdate's job is to drop extra messages in the buffer, but I don't seem to be dropping any on the receiving end (as I have them indexed), so I'm not quite sure why Unreliable has extra messages in it's buffer over StateUpdate, but if I do figure it out I'll post it here.

    Thanks for the help!

    EDIT: Even with the QoS on StateUpdate, every now and again the messages get double read in a single frame. This is with the max delay set to the float.MinValue. It happens far less than Reliable, but maybe 10-15 times per thousand messages. The plot thickens.
     
    Last edited: Oct 28, 2015