Hi. I have a really simple setup using the ReliableSequencedPipelineStage (2.0.0-pre.2, Unity 2022.2.0b8) where messages are being dropped without any kind of console message (I am aware of the 32 limit but it is no showing up in console, I am not sure if it is the same problem).
The server code sends a uint for every frame and client prints an error for every number missing.
To reproduce:
- in two different unity editors add the “Menu” script to some game object and play
- in one editor click “Start server”
- in a second editor click “Start client”
- in the first editor click “Start simulation”
Server will start to send numers to the client, server and client will log those numbers. - click the second editor
When second editor gains focus, after a mini halt, some messages will be skipped and the missing numbers will be logged as errors.
using Unity.Networking.Transport;
using UnityEngine;
public class Menu : MonoBehaviour
{
private Server server;
private Client client;
private bool serverRunning;
private bool clientRunning;
private void OnGUI()
{
if (!serverRunning && !clientRunning && GUILayout.Button("Start server"))
{
server = new Server();
var endpoint = NetworkEndpoint.AnyIpv4;
endpoint.Port = 9000;
server.Initialize(endpoint);
serverRunning = true;
}
if (!serverRunning && !clientRunning && GUILayout.Button("Start client"))
{
client = new Client();
client.Initialize(NetworkEndpoint.Parse("127.0.0.1", 9000));
clientRunning = true;
}
if (serverRunning && GUILayout.Button("Start simulation"))
{
server.sendTest = true;
}
}
void Update()
{
if(serverRunning) server.Update();
if(clientRunning) client.Update();
}
}
using System;
using Unity.Collections;
using Unity.Networking.Transport;
using UnityEngine;
public struct Server : IDisposable
{
private NetworkDriver driver;
private NetworkPipeline pipeline;
private NativeList<NetworkConnection> connections;
public bool sendTest;
private uint acc;
public void Initialize(NetworkEndpoint endpoint)
{
Debug.Log($"SERVER: Initializing at " + endpoint.ToString());
var settings = new NetworkSettings();
settings.WithNetworkConfigParameters(disconnectTimeoutMS: 3600000);
driver = NetworkDriver.Create(settings);
pipeline = driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));
if (driver.Bind(endpoint) != 0)
Debug.Log($"SERVER: Failed to bind to port {endpoint.Port}");
else
driver.Listen();
connections = new NativeList<NetworkConnection>(16, Allocator.Persistent);
}
public void Dispose()
{
driver.Dispose();
connections.Dispose();
}
public void Update()
{
driver.ScheduleUpdate().Complete();
// CleanUpConnections
for (int i = connections.Length - 1; i >= 0; i--)
{
if (!connections[i].IsCreated)
{
connections.RemoveAt(i);
}
}
// AcceptNewConnections
NetworkConnection newConnection;
while ((newConnection = driver.Accept()) != default)
{
connections.Add(newConnection);
Debug.Log($"SERVER: Accepted a connection: clientIndex = {connections.Length - 1}");
}
// Handle messages
for (int clientIndex = 0; clientIndex < connections.Length; clientIndex++)
{
var connection = connections[clientIndex];
NetworkEvent.Type cmd;
while ((cmd = driver.PopEventForConnection(connection, out var reader)) != NetworkEvent.Type.Empty)
{
if (cmd == NetworkEvent.Type.Data)
{
}
else if (cmd == NetworkEvent.Type.Disconnect)
{
Debug.Log($"SERVER: Client disconnected from server: clientIndex = {clientIndex}");
connections[clientIndex] = default(NetworkConnection);
}
}
}
if (sendTest)
{
acc++;
Debug.Log($"Sending {acc}");
for (int i = 0; i < connections.Length; i++)
{
var connection = connections[i];
driver.BeginSend(pipeline, connection, out var writer);
writer.WriteUInt(acc);
driver.EndSend(writer);
}
}
}
}
using System;
using Unity.Networking.Transport;
using UnityEngine;
public struct Client : IDisposable
{
public NetworkDriver driver;
public NetworkPipeline pipeline;
public NetworkConnection connection;
public uint acc;
public void Initialize(NetworkEndpoint endPoint)
{
Debug.Log($"CLIENT: Connecting to server in {endPoint.ToString()}");
var settings = new NetworkSettings();
settings.WithNetworkConfigParameters(disconnectTimeoutMS: 3600000);
driver = NetworkDriver.Create(settings);
pipeline = driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));
connection = driver.Connect(endPoint);
}
public void Dispose()
{
driver.Dispose();
}
public void Update()
{
driver.ScheduleUpdate().Complete();
if (!connection.IsCreated)
{
Debug.Log("CLIENT: Connection failed");
return;
}
var cmd = default(NetworkEvent.Type);
while ((cmd = connection.PopEvent(driver, out var reader)) != default)
{
switch (cmd)
{
case NetworkEvent.Type.Connect:
{
Debug.Log("CLIENT: Connected to server");
break;
}
case NetworkEvent.Type.Data:
{
var serverAcc = reader.ReadUInt();
while (serverAcc > acc + 1)
{
Debug.LogError($"Missing {++acc}");
}
Debug.Log($"Receiving {serverAcc}");
acc = serverAcc;
break;
}
case NetworkEvent.Type.Disconnect:
{
Debug.Log("CLIENT: Disconnected from server");
connection = default(NetworkConnection);
break;
}
default: throw new Exception();
}
}
}
}