Unity-Technologies / multiplayer-community-contributions

Community contributions to Unity Multiplayer Networking products and services.
MIT License
421 stars 161 forks source link

Error when running Example Network Discovery #193

Open MrPure3D opened 1 year ago

MrPure3D commented 1 year ago

Hi,

Im getting this error on Server when Client is Searching for a Server, this on Both Apple M1 and Windows. port on NetworkManager: 7770 and local IP Port on ExampleNetworkDiscovery: 47777

Any ideas?

Invalid allocation label passed to UnsafeUtility::Free UnityEngine.StackTraceUtility:ExtractStackTrace () Unity.Netcode.FastBufferWriter:Dispose () (at Library/PackageCache/com.unity.netcode.gameobjects@1.2.0/Runtime/Serialization/FastBufferWriter.cs:125) NetworkDiscovery`2/d__27<DiscoveryBroadcastData, DiscoveryResponseData>:MoveNext () (at Library/PackageCache/com.community.netcode.extensions@e9f53f86a0/Runtime/NetworkDiscovery/NetworkDiscovery.cs:224) UnityEngine.UnitySynchronizationContext:ExecuteTasks ()

unnanego commented 1 year ago

Same here

paatz04 commented 1 year ago

same here

Kinggrass commented 1 year ago

Unfortunatly the same :(

Kinggrass commented 1 year ago

Don't know what explicitly is wrong, but I explicitly disposed the FastBufferWriter and now it don't appear anymore. By changing from following in NetworkDiscovery.cs: image

to:

image

Kinggrass commented 1 year ago

Maybe the underlying handle is not valid anymore after the async task is returning. Maybe the author could better explain what could happen here.

yannoid commented 1 year ago

Same here.

Removing the error with @Kinggrass 's solution won't work for me since it doesn't connect the client after that.

jpvanoosten commented 1 year ago

The issue occurs because the FastBufferWriter uses Allocator.Temp for the memory allocation which very likely results in the memory handle becoming invalid at the end of the current frame (the backing memory for the FastBufferWriter is disposed before the FastBufferWriter using that memory is disposed). Since this is an async method, there is no guarantee the function will complete within 1 frame. If the SendAsync function doesn't return immediately, then the error will occur.

To fix this, change Allocator.Temp to Allocator.Persistent when creating a FastBufferReader or FastBufferWriter inside of an async function. For example, this is what ReceiveBroadcastAsync should look like:

    async Task ReceiveBroadcastAsync()
    {
        UdpReceiveResult udpReceiveResult = await m_Client.ReceiveAsync();

        var segment = new ArraySegment<byte>(udpReceiveResult.Buffer, 0, udpReceiveResult.Buffer.Length);
        using var reader = new FastBufferReader(segment, Allocator.Persistent);

        try
        {
            if (ReadAndCheckHeader(reader, MessageType.BroadCast) == false)
            {
                return;
            }

            reader.ReadNetworkSerializable(out TBroadCast receivedBroadcast);

            if (ProcessBroadcast(udpReceiveResult.RemoteEndPoint, receivedBroadcast, out TResponse response))
            {
                using var writer = new FastBufferWriter(1024, Allocator.Persistent, 1024 * 64);
                WriteHeader(writer, MessageType.Response);

                writer.WriteNetworkSerializable(response);
                var data = writer.ToArray();

                await m_Client.SendAsync(data, data.Length, udpReceiveResult.RemoteEndPoint);
            }
        }
        catch (Exception e)
        {
            Debug.LogException(e);
        }
    }

The ReceiveResponseAsync method should also be updated accordingly.

MattGrayUL commented 1 year ago

The solution from @jpvanoosten fixed the issue for me