private static async Task <int> Connect( string addressString, string portString, string localAddressString, string localPortString) { var remoteEndPoint = ParseEndPoint(addressString, portString); var localEndPoint = ParseEndPoint(localAddressString, localPortString); var builder = new ClientBuilder(); builder.AddDebugging(LogEventLevel.Verbose); builder.AddPeers() .AddPeerListener <PeerHandler>(); builder.AddState() .AddStateListener <StateHandler>() .UpdatePeers() .AddStateListener <StateHandler>(); builder.ConnectTo(options => { options.RemoteEndPoint = remoteEndPoint; options.LocalEndPoint = null;//localEndPoint; }); var client = builder.Build(); client.OnConnected += clientId => { client.ServiceProvider.GetRequiredService <ILogger>().Information("Client connected; assigned {ClientId:s}", clientId); return(Task.CompletedTask); }; client.OnDisconnected += clientId => { client.ServiceProvider.GetRequiredService <ILogger>().Information("Client disconnected as {ClientId:s}", clientId); _closedEvent.Set(); return(Task.CompletedTask); }; await client.StartAsync(); var _ = Task.Run(async() => { var position = new StateMessage { X = 0, Y = 0 }; var random = new Random(); while (true) { await Task.Delay(1000); position = client.State().GetState() == null ? position : (StateMessage)client.State().GetState(); position.X += random.NextDouble() - .5; position.Y += random.NextDouble() - .5; var logger = client.ServiceProvider.GetRequiredService <ILogger>(); logger.ForContext <Program>().Information("Client {ClientId:s} sending state = {Position}", client.Id, position); await client.UpdateStateAsync(position); } }); await _closedEvent.WaitAsync(); return(0); }