Search Unity

Why UNet(LLAPI) Very Slow ?

Discussion in 'UNet' started by nomadshiba, Jun 6, 2017.

  1. nomadshiba

    nomadshiba

    Joined:
    Jun 22, 2015
    Posts:
    27
    First of all sorry for my English.

    I have tried both of System.Net.Sockets.UdpClient and NetworkTransport.

    There is no problem with UdpClient really smooth no lag. (1 client, (200 Vector3)*9 per second)
    But when I try to do the same test with NetworkTransport it's very laggy. (Unreliable Channel)(3 to 5 second delay and really laggy)
    (I'm using same serialization method for both methods.)

    I don't understand why even LLAPI is very slow.
    After all, both of them are UDP. Right?

    Edit:
    I think the problem is about Update Method. It's able to receive just one data per frame.
     
    Last edited: Jun 6, 2017
  2. TomPo

    TomPo

    Joined:
    Nov 30, 2013
    Posts:
    86
    FixedUpdate is running once per frame, not Update. If you are using same serialization method (with same async) problem may be somewhere else. Where? Hard to find out without a code and more data, like testing on one machine locally or via real net ?
     
  3. spacefrog

    spacefrog

    Joined:
    Jun 14, 2009
    Posts:
    734
    You have things reversed: Update() is run once per frame, FixedUpdate() is run once per a set fixed rate ( hence the name) . The fixed rate is set by the Time->Fixed Timestep. This value defines the physics update rate too
     
  4. TomPo

    TomPo

    Joined:
    Nov 30, 2013
    Posts:
    86
    yes, of course you are righnt. Have no idea about what i was thinking writing this :)
     
  5. nomadshiba

    nomadshiba

    Joined:
    Jun 22, 2015
    Posts:
    27
    Sorry for my late reply. I was studying for my exams. :)

    I have my own NetworkManager.
    • It's based on Server/Client system.
    • It can adapt to any kind of Networking infrastructure.
    • I have some Objects(Class) that called as "NObject". It basically stores some data for sync.
    • And NClientEye manages those objects.
    First, I built it on Unity Networking(LLAPI). Then I tried it with (1 client, (200 Vector3)*9 per second).
    1. To do this have created 200 NObject.
    2. And I did set NTransform update rate of those objects as 9 Update per second.
    3. Then I connected a client(local). And I wrote a basic script to move objects forward and backward.
    In Unity.Networking was lagging and moving like every 0.5 seconds. (There is no FPS drop)
    Then I have tried it with a basic UdpClient(System.Net.Sockets)

    Same system, same codes, same serialization methods. No difference except Library.

    And everything was fine. There was no lag or delay, everything very smooth.

    Everything same except those two parts.

    UDP codes:
    Code (CSharp):
    1. /*
    2.     -----------------------
    3.     UDP-Send
    4.     -----------------------
    5.     // [url]http://msdn.microsoft.com/de-de/library/bb979228.aspx#ID0E3BAC[/url]
    6. */
    7. using UnityEngine;
    8. using System.Collections;
    9. using System.Collections.Generic;
    10. using System;
    11. using System.Text;
    12. using System.Net;
    13. using System.Net.Sockets;
    14. using System.Threading;
    15. using UnityEngine.Networking;
    16.  
    17. public class UDP : MonoBehaviour
    18. {
    19.  
    20.     public ServerManager manager;
    21.  
    22.     public string IP;
    23.     public int port;
    24.  
    25.     UdpClient myClient;
    26.  
    27.     public List<NetworkMessage> allReceivedUDPPackets = new List<NetworkMessage>();
    28.     private object _sync = new object();
    29.  
    30.     public void Start()
    31.     {
    32.         manager = GetComponent<ServerManager>();
    33.         init();
    34.     }
    35.  
    36.     // init
    37.     public void init()
    38.     {
    39.         receiveThread = new Thread(
    40.         new ThreadStart(receiveData));
    41.         receiveThread.IsBackground = true;
    42.         receiveThread.Start();
    43.     }
    44.  
    45.     // sendData
    46.     public static void sendData(UdpClient client, Message msg)
    47.     {
    48.         try
    49.         {
    50.             //IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
    51.  
    52.             NetworkWriter writer = new NetworkWriter();
    53.             msg.Serialize(writer);
    54.             byte[] data = writer.AsArray();
    55.             client.Send(data, data.Length);
    56.         }
    57.         catch (Exception err)
    58.         {
    59.             print(err);
    60.         }
    61.     }
    62.  
    63.     private void Update()
    64.     {
    65.         lock (_sync)
    66.         {
    67.             for (int i = 0; i < allReceivedUDPPackets.Count; i++)
    68.                 manager.Message(allReceivedUDPPackets[i]);
    69.             allReceivedUDPPackets.Clear();
    70.         }
    71.     }
    72.  
    73.     Thread receiveThread;
    74.     private void receiveData()
    75.     {
    76.  
    77.         myClient = new UdpClient(port);
    78.         while (true)
    79.         {
    80.  
    81.             try
    82.             {
    83.                 IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
    84.                 byte[] data = myClient.Receive(ref anyIP);
    85.  
    86.                 NetworkReader reader = new NetworkReader(data);
    87.                 NetworkMessage msg = new NetworkMessage();
    88.                 msg.reader = reader;
    89.  
    90.  
    91.                 lock (_sync)
    92.                 {
    93.                     allReceivedUDPPackets.Add(msg);
    94.                 }
    95.             }
    96.             catch (Exception err)
    97.             {
    98.                 print(err.ToString());
    99.             }
    100.         }
    101.     }
    102.  
    103.     private void OnDisable()
    104.     {
    105.         Close();
    106.     }
    107.  
    108.     private void OnApplicationQuit()
    109.     {
    110.         Close();
    111.     }
    112.  
    113.     void Close()
    114.     {
    115.         receiveThread.Abort();
    116.         myClient.Close();
    117.     }
    118.  
    119. }
    Unity.Networking Receive codes:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         int recHostId;
    4.         int connectionId;
    5.         int channelId;
    6.         byte[] recBuffer = new byte[3072];
    7.         int bufferSize = 3072;
    8.         int dataSize;
    9.         byte error;
    10.         NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    11.         switch (recData)
    12.         {
    13.             case NetworkEventType.ConnectEvent:    //2
    14.                 OnConnect(connectionId);
    15.                 break;
    16.             case NetworkEventType.DataEvent:       //3
    17.  
    18.                 NetworkReader reader = new NetworkReader(recBuffer);
    19.                 NetworkMessage msg = new NetworkMessage();
    20.                 msg.reader = reader;
    21.  
    22.                 Message(msg);
    23.                 break;
    24.             case NetworkEventType.DisconnectEvent: //4
    25.                 OnDisconnect(connectionId);
    26.                 break;
    27.         }
    28.     }

    200 FPS on the client.
    And its receive just one message per frame.
    I have 200*9 message per second. (1800 message per second).
    1800-200 = 1600 lost message.
    So it's not enough to receive all the messages. This explains why some objects don't sync at the time.

    But the part I couldn't understand why there is a delay.
    I mean even after objects stop moving on the server side, some objects still moving with a delay on the client side. It's like there's a queue. but I'm using the Unreliable channel.

    If I can't find any solution then I have to write my own Networking system and Connection manager based on System.Net.Sockets.
     
    Last edited: Jun 11, 2017
  6. Driiades

    Driiades

    Joined:
    Oct 27, 2015
    Posts:
    151
    Are you sure to send data in an Unreliable channel ?
     
  7. nomadshiba

    nomadshiba

    Joined:
    Jun 22, 2015
    Posts:
    27
    At First, I suspected about this too. But its works right.

    Code (CSharp):
    1.         config.Channels.Clear();
    2.         config.AddChannel(QosType.Unreliable);
    3.         config.AddChannel(QosType.UnreliableFragmented);
    4.         config.AddChannel(QosType.UnreliableSequenced);
    5.         config.AddChannel(QosType.Reliable);
    6.         config.AddChannel(QosType.ReliableFragmented);
    7.         config.AddChannel(QosType.ReliableSequenced);
    8.         config.AddChannel(QosType.StateUpdate);
    9.         config.AddChannel(QosType.ReliableStateUpdate);
    10.         config.AddChannel(QosType.AllCostDelivery);
    I am using channel 0 to send Unreliable Message.
     
  8. Ellernate

    Ellernate

    Joined:
    Aug 25, 2017
    Posts:
    81
    Hello, I was having some trouble with this and in my opinion it's due to poor documentation on the transport layer. Using the documentation example, you'll find that the server is only processing 1 packet per frame in Update. I checked the HLAPI's source to find unity's own solution. Implement a loop to process queued packets and the delay should go away.

    Code (CSharp):
    1.         private void Update()
    2.         {
    3.             NetworkEventType fromHost;
    4.             do
    5.             {
    6.                 int connectionId;
    7.                 int channelId;
    8.                 int receivedSize;
    9.                 fromHost = NetworkTransport.ReceiveFromHost(this.m_ServerHostId, out connectionId, out channelId,
    10.                     this.m_MsgBuffer, this.m_MsgBuffer.Length, out receivedSize, out error);
    11.                 if (fromHost == NetworkEventType.Nothing)
    12.                     ;
    13.                 switch (fromHost)
    14.                 {
    15.                     case NetworkEventType.DataEvent:
    16.                         this.HandleData(connectionId, channelId, receivedSize, error);
    17.                         goto case NetworkEventType.Nothing;
    18.                     case NetworkEventType.ConnectEvent:
    19.                         this.HandleConnect(connectionId, error);
    20.                         goto case NetworkEventType.Nothing;
    21.                     case NetworkEventType.DisconnectEvent:
    22.                         this.HandleDisconnect(connectionId, error);
    23.                         goto case NetworkEventType.Nothing;
    24.                     case NetworkEventType.Nothing:
    25.                         continue;
    26.                     default:
    27.                         if (LogFilter.logError)
    28.                         {
    29.                             Debug.LogError((object)("Unknown network message type received: "
    30.                                                         + (object)fromHost));
    31.                             goto case NetworkEventType.Nothing;
    32.                         }
    33.                         else
    34.                             goto case NetworkEventType.Nothing;
    35.                 }
    36.             }
    37.             while (fromHost != NetworkEventType.Nothing);
    38.         }
     
  9. Deleted User

    Deleted User

    Guest

    Hello.
    Is it modified HLAPI snippet of code?