static NetworkConnection ProcessSingleConnection(NetworkDriver.Concurrent driver, NetworkConnection connection) { DataStreamReader strm; NetworkEvent.Type cmd; // Pop all events for the connection while ((cmd = driver.PopEventForConnection(connection, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Data) { // For ping requests we reply with a pong message int id = strm.ReadInt(); // Create a temporary DataStreamWriter to keep our serialized pong message if (driver.BeginSend(connection, out var pongData) == 0) { pongData.WriteInt(id); // Send the pong message with the same id as the ping driver.EndSend(pongData); } } else if (cmd == NetworkEvent.Type.Disconnect) { // When disconnected we make sure the connection return false to IsCreated so the next frames // DriverUpdateJob will remove it return(default(NetworkConnection)); } } return(connection); }
public unsafe void Execute(int index) { DataStreamReader streamReader; Assert.IsTrue(Connections[index].IsCreated); NetworkEvent.Type command; while ((command = Driver.PopEventForConnection(Connections[index], out streamReader)) != NetworkEvent.Type.Empty) { if (command == NetworkEvent.Type.Data) { QueueMessage(ref streamReader, index); } else if (command == NetworkEvent.Type.Connect) { var d = new RawNetworkMessage() { Length = 0, Type = (uint)MLAPINetworkEvent.Connect, Id = index }; PacketData.Enqueue(d); } else if (command == NetworkEvent.Type.Disconnect) { var d = new RawNetworkMessage() { Length = 0, Type = (uint)MLAPINetworkEvent.Disconnect, Id = index }; PacketData.Enqueue(d); Connections[index] = default; } } }
public void Execute(int index) { DataStreamReader stream; Assert.IsTrue(connections[index].IsCreated); NetworkEvent.Type cmd; while ((cmd = driver.PopEventForConnection(connections[index], out stream)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Data) { NativeString64 message = stream.ReadString(); if (message.ToString() != "Message Confirmed") { Debug.Log("Received Message: " + message); var writer = driver.BeginSend(connections[index]); writer.WriteString("Message Confirmed"); driver.EndSend(writer); } } else if (cmd == NetworkEvent.Type.Disconnect) { Debug.Log("Client disconnected from server"); connections[index] = default(NetworkConnection); } } }
// -- IJob -- public void Execute(int ci) { DataStreamReader stream; Assert.IsTrue(mConnections[ci].IsCreated); NetworkEvent.Type cmd; while ((cmd = mDriver.PopEventForConnection(mConnections[ci], out stream)) != NetworkEvent.Type.Empty) { switch (cmd) { case NetworkEvent.Type.Data: { // read number of events var n = stream.ReadByte(); Log.D($"Host - received {n} events from client {ci}"); // read events out of stream var events = new AnyEvent[n]; for (var i = 0; i < n; i++) { events[i] = new AnyEvent( step: stream.ReadUInt(), new AnyEvent.Value( type: (EventType)stream.ReadByte() ) ); } // route events back to every client for (var i = 0; i < mConnections.Length; i++) { var writer = mDriver.BeginSend(mConnections[i]); // write the number of events writer.WriteByte(n); // write each event foreach (var evt in events) { writer.WriteUInt(evt.Step); writer.WriteByte((byte)evt.Val.Type); } mDriver.EndSend(writer); } break; } case NetworkEvent.Type.Disconnect: { Log.I($"Host - client {ci} disconnected"); mConnections[ci] = default; break; } } } }
public void Execute(int i) { SoakMessage inbound = default(SoakMessage); SoakMessage outbound = default(SoakMessage); if (connections[i].Connection.IsCreated) { var ctx = connections[i]; DataStreamReader strm; NetworkEvent.Type cmd; bool close = false; while ((cmd = driver.PopEventForConnection(ctx.Connection, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Data) { unsafe { strm.ReadBytes(inbound.data, strm.Length); Assert.AreEqual(strm.Length, inbound.length + SoakMessage.HeaderLength); outbound.id = inbound.id; outbound.sequence = ctx.NextSequenceId++; if (driver.BeginSend(pipeline, connections[i].Connection, out var soakData) == 0) { soakData.WriteBytes(outbound.data, SoakMessage.HeaderLength); driver.EndSend(soakData); } } } else if (cmd == NetworkEvent.Type.Disconnect) { close = true; } } if (close) { ctx.Connection = default(NetworkConnection); ctx.NextSequenceId = -1; } connections[i] = ctx; } }
public void Execute(ref PingServerConnectionComponentData connection) { DataStreamReader strm; NetworkEvent.Type cmd; while ((cmd = driver.PopEventForConnection(connection.connection, out strm)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Data) { int id = strm.ReadInt(); var pongData = driver.BeginSend(connection.connection); pongData.WriteInt(id); driver.EndSend(pongData); } else if (cmd == NetworkEvent.Type.Disconnect) { connection = new PingServerConnectionComponentData { connection = default(NetworkConnection) }; } } }
public unsafe void Execute(Entity entity, int index, ref NetworkStreamConnection connection, ref NetworkSnapshotAckComponent snapshotAck) { if (!connection.Value.IsCreated) { return; } DataStreamReader reader; NetworkEvent.Type evt; while ((evt = driver.PopEventForConnection(connection.Value, out reader)) != NetworkEvent.Type.Empty) { switch (evt) { case NetworkEvent.Type.Connect: break; case NetworkEvent.Type.Disconnect: // Flag the connection as lost, it will be deleted in a separate system, giving user code one frame to detect and respond to lost connection commandBuffer.AddComponent(index, entity, new NetworkStreamDisconnected { Reason = NetworkStreamDisconnectReason.ConnectionClose }); rpcBuffer[entity].Clear(); cmdBuffer[entity].Clear(); connection.Value = default(NetworkConnection); if (networkId.Exists(entity)) { freeNetworkIds.Enqueue(networkId[entity].Value); } return; case NetworkEvent.Type.Data: // FIXME: do something with the data switch ((NetworkStreamProtocol)reader.ReadByte()) { case NetworkStreamProtocol.Command: { var buffer = cmdBuffer[entity]; #if UNITY_EDITOR || DEVELOPMENT_BUILD if (buffer.Length > 0) { netStats[0] = netStats[0] + 1; } #endif // FIXME: should be handle by a custom command stream system uint snapshot = reader.ReadUInt(); uint snapshotMask = reader.ReadUInt(); snapshotAck.UpdateReceivedByRemote(snapshot, snapshotMask); uint remoteTime = reader.ReadUInt(); uint localTimeMinusRTT = reader.ReadUInt(); uint interpolationDelay = reader.ReadUInt(); snapshotAck.UpdateRemoteTime(remoteTime, localTimeMinusRTT, localTime, interpolationDelay); buffer.Clear(); buffer.Add(ref reader); break; } case NetworkStreamProtocol.Snapshot: { uint remoteTime = reader.ReadUInt(); uint localTimeMinusRTT = reader.ReadUInt(); snapshotAck.ServerCommandAge = reader.ReadInt(); snapshotAck.UpdateRemoteTime(remoteTime, localTimeMinusRTT, localTime, 0); var buffer = snapshotBuffer[entity]; #if UNITY_EDITOR || DEVELOPMENT_BUILD if (buffer.Length > 0) { netStats[0] = netStats[0] + 1; } #endif buffer.Clear(); buffer.Add(ref reader); break; } case NetworkStreamProtocol.Rpc: { var buffer = rpcBuffer[entity]; buffer.Add(ref reader); break; } default: #if ENABLE_UNITY_COLLECTIONS_CHECKS throw new InvalidOperationException("Received unknown message type"); #else break; #endif } break; default: #if ENABLE_UNITY_COLLECTIONS_CHECKS throw new InvalidOperationException("Received unknown network event " + evt); #else break; #endif } } }