Unity-Technologies / Unity-Technologies/multiplayer-community-contributions

Number of errors when implementing new transport

Open
#77 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

type:support
Dominant language
C#
Stars
555
Forks
197
Avg merge
4d 12h
Merged PRs (30d)
1

Description

Hi there, I'm getting a number of MLAPI errors while building a SteamNetworkingSockets transport and I'd love some help.

The transport appears to be partially working. The host sometimes doesn't display one or the other player, and sometimes players lag badly. Seems to be luck of the draw.

I have a feeling I'm doing something like leaving old data in the send and receive buffers between events but I don't know enough about buffers in c# to intuit the answer.

Buffers are created like so, taken verbatim from https://github.com/rlabrecque/Steamworks.NET/issues/411#issuecomment-826115503:

     IntPtr sendBuffer = Marshal.AllocHGlobal(65536);
     IntPtr[] receiveBuffers = new IntPtr[1]; // given PollEvent returns a single NetworkEvent, it seems we can only handle one message at a time.

The relevant Send code:

    public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChannel channel)
    {
      int nSendFlags = ChannelSendFlags[channel];
      HSteamNetConnection sendToHConn = isServer ? steamIdToHConn[clientId] : serverHConn;

      Debug.Log($"Send(clientId {clientId}, data {data}, channel {channel});");

      try
      {
        Marshal.Copy(data.Array, 0, sendBuffer, data.Array.Length);
        SteamNetworkingSockets.SendMessageToConnection(sendToHConn, sendBuffer, (uint)data.Array.Length, nSendFlags, out _);
      }
      catch
      {
        Marshal.FreeHGlobal(sendBuffer);
      }
    }

The relevant PollEvent code:

      // if there are no messages, return
      if (messageCount > 0)
      {
        Debug.Log($"PollEvent(); // messageCount is {messageCount}");
        try
        {
          SteamNetworkingMessage_t netMessage = Marshal.PtrToStructure<SteamNetworkingMessage_t>(receiveBuffers[0]);
          byte[] message = new byte[netMessage.m_cbSize];
          Marshal.Copy(netMessage.m_pData, message, 0, message.Length);

          payload = new ArraySegment<byte>(message);
          clientId = netMessage.m_identityPeer.GetSteamID64();

          Debug.Log($"PollEvent(); // message received at {receiveTime} from {clientId}");

          SteamAPI_SteamNetworkingMessage_t_Release(receiveBuffers[0]);
        }
        finally
        {
          Marshal.DestroyStructure<SteamNetworkingMessage_t>(receiveBuffers[0]);
        }
        return NetworkEvent.Data;
      }

Any guidance on how to fix this would be appreciated.

These errors are occasionally appearing in both consoles:

OSXPlayer(Alices-MacBook-Air.local) RpcQueueContainer 65 update type does not exist!
UnityEngine.StackTraceUtility:ExtractStackTrace () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/StackTrace.cs:37)
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:LogError (object)
MLAPI.Messaging.RpcQueueContainer:GetQueueHistoryFrame (MLAPI.Messaging.RpcQueueHistoryFrame/QueueFrameType,MLAPI.NetworkUpdateStage,bool) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs:567)
MLAPI.Messaging.RpcQueueContainer:AddQueueItemToInboundFrame (MLAPI.Messaging.RpcQueueContainer/QueueItemType,single,ulong,MLAPI.Serialization.NetworkBuffer) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs:284)
MLAPI.Messaging.InternalMessageHandler:RpcReceiveQueueItem (ulong,System.IO.Stream,single,MLAPI.Messaging.RpcQueueContainer/QueueItemType) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/InternalMessageHandler.cs:568)
MLAPI.NetworkManager:ReceiveCallback (MLAPI.Serialization.NetworkBuffer,MLAPI.Messaging.RpcQueueContainer/QueueItemType,ulong,single) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:1094)
MLAPI.Messaging.RpcBatcher:ReceiveItems (MLAPI.Serialization.NetworkBuffer&,MLAPI.Messaging.RpcBatcher/ReceiveCallbackType,MLAPI.Messaging.RpcQueueContainer/QueueItemType,ulong,single) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcBatcher.cs:216)
MLAPI.NetworkManager:HandleIncomingData (ulong,MLAPI.Transports.NetworkChannel,System.ArraySegment`1<byte>,single,bool) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:1060)
MLAPI.NetworkManager:HandleRawTransportPoll (MLAPI.Transports.NetworkEvent,ulong,MLAPI.Transports.NetworkChannel,System.ArraySegment`1<byte>,single) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:875)
MLAPI.NetworkManager:OnNetworkEarlyUpdate () (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:683)
MLAPI.NetworkManager:NetworkUpdate (MLAPI.NetworkUpdateStage) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:641)
MLAPI.NetworkUpdateLoop:RunNetworkUpdateStage (MLAPI.NetworkUpdateStage) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:148)
MLAPI.NetworkUpdateLoop/NetworkEarlyUpdate/<>c:<CreateLoopSystem>b__0_0 () (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:171)

(Filename: /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs Line: 567)

The number 65 is different every time. Always a uint8, so seems to be a byte out of place.

This one is caused by the last one:

OSXPlayer(Alices-MacBook-Air.local) NullReferenceException: Object reference not set to an instance of an object
  at MLAPI.Messaging.RpcQueueContainer.AddQueueItemToInboundFrame (MLAPI.Messaging.RpcQueueContainer+QueueItemType qItemType, System.Single timeStamp, System.UInt64 sourceNetworkId, MLAPI.Serialization.NetworkBuffer message) [0x00050] in /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs:285 
  at MLAPI.Messaging.InternalMessageHandler.RpcReceiveQueueItem (System.UInt64 clientId, System.IO.Stream stream, System.Single receiveTime, MLAPI.Messaging.RpcQueueContainer+QueueItemType queueItemType) [0x00073] in /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/InternalMessageHandler.cs:568 

And finally

ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
System.Buffer.BlockCopy (System.Array src, System.Int32 srcOffset, System.Array dst, System.Int32 dstOffset, System.Int32 count) (at <695d1cc93cca45069c528c15c9fdd749>:0)
MLAPI.Messaging.RpcBatcher.ReceiveItems (MLAPI.Serialization.NetworkBuffer& messageBuffer, MLAPI.Messaging.RpcBatcher+ReceiveCallbackType receiveCallback, MLAPI.Messaging.RpcQueueContainer+QueueItemType messageType, System.UInt64 clientId, System.Single receiveTime) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcBatcher.cs:214)
MLAPI.NetworkManager.HandleIncomingData (System.UInt64 clientId, MLAPI.Transports.NetworkChannel networkChannel, System.ArraySegment`1[T] data, System.Single receiveTime, System.Boolean allowBuffer) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:1042)
MLAPI.NetworkManager.HandleRawTransportPoll (MLAPI.Transports.NetworkEvent networkEvent, System.UInt64 clientId, MLAPI.Transports.NetworkChannel networkChannel, System.ArraySegment`1[T] payload, System.Single receiveTime) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:875)
MLAPI.NetworkManager.OnNetworkEarlyUpdate () (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:683)
MLAPI.NetworkManager.NetworkUpdate (MLAPI.NetworkUpdateStage updateStage) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:641)
MLAPI.NetworkUpdateLoop.RunNetworkUpdateStage (MLAPI.NetworkUpdateStage updateStage) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:148)
MLAPI.NetworkUpdateLoop+NetworkEarlyUpdate+<>c.<CreateLoopSystem>b__0_0 () (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:171)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the custom transport's Send and PollEvent paths, then compare their payload handling with RpcBatcher.ReceiveItems and RpcQueueContainer.AddQueueItemToInboundFrame in the stack traces. Reproduce the intermittent errors with the SteamNetworkingSockets transport and verify that players are displayed reliably without lag or buffer-related exceptions.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.