public void Receive(Socket socket, ReceivedPacket packet) { try { if (HasTimedOut) { return; } _lastReceivedTime = DateTime.Now; // If we have already acked, then reack if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.AckRequest) && IsPacketCoveredByAck(_readyToAck.GetValueOrDefault(0), packet.PacketId)) { QueueOrSendAck(socket, packet.PacketId); return; } // If we have skipped something, then discard if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.AckRequest) && packet.PacketId != IncrementPacketId(_readyToAck.GetValueOrDefault(0))) { Log.DebugFormat("{0} - Discarding message received out of order Got:{1} Expected:{2}", Endpoint, packet.PacketId, _readyToAck); return; } // Handle it if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.AckRequest)) { QueueOrSendAck(socket, packet.PacketId); } Log.DebugFormat("{0} - Command {1}, Length {2}, Session {3:X}, Acked {4}, Packet {5}", Endpoint, packet.CommandCode, packet.PayloadLength, packet.SessionId, packet.AckedId, packet.PacketId); if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.AckReply)) { _isOpen = true; if (!_lastReceivedAck.HasValue || !IsPacketCoveredByAck(_lastReceivedAck.Value, packet.AckedId)) { _lastReceivedAck = packet.AckedId; } } if (packet.CommandCode.HasFlag(ReceivedPacket.CommandCodeFlags.AckRequest)) { Log.DebugFormat("{0} - Parsed {1} commands with length {2}", Endpoint, packet.Commands.Count, packet.PayloadLength); _processQueue.Add(packet); OnReceivePacket?.Invoke(this, packet); } // Note: Handshake is handled elsewhere // Note: Unknown, Retransmit both need no action } catch (ArgumentException) { //discard as was malformed } }
private void ForwardAllIncomingPackets() { Queue <BasePacket> packets; lock (packetLock) { packets = incomingPackets; incomingPackets = new Queue <BasePacket>(); } foreach (var packet in packets) { OnReceivePacket?.Invoke(packet); } }
public void Connect(ClientSocket.OnConnect onConnect, OnReceivePacket onReceivePacket) { netThreadDispatcher.Dispatch(() => { client.AsyncConnect((bool success) => { if (success) { StartReceive(onReceivePacket); } Dispatcher.Main.Dispatch(() => { onConnect.Invoke(success); }); }); }); }
/// <summary> /// Handles a received packet. Welcome packets are handled internally. /// </summary> void HandlePacket(PacketId packetId, Packet packet) { if (packetId == PacketId.WelcomeResponse) { WelcomeResponse(packet); } else { //dispatch local client event. OnReceivePacket.Invoke(packet); //dispatch global server event. OnClientReceivePacket(this, packet); } }
/// <summary> /// Receives a package and handles the welcome package. Welcome packets are handled internally. /// </summary> static void OnHandleData(byte[] data) { var packet = new Packet(data); var packetId = (PacketId)packet.ReadInt(); packet.SetId(packetId); if (packetId == PacketId.Welcome) { OnWelcome(packet); } else { OnReceivePacket.Invoke(packet); } }
internal void StartReceive(OnReceivePacket onReceivePacket) { netThreadDispatcher.Dispatch(() => { client.AsyncReceive(buffer, (byte [] data, int bytesReceived) => { int offset = 0; LuaTable packet = parseDecode(data, out offset); while (packet != null) { Dispatcher.Main.Dispatch(() => { onReceivePacket(packet); }); packet = parseDecode(data, out offset); } if (offset > 0) { int remainBytes = bytesReceived - offset; if (data.Length > HIGH_BUF_SIZE) { // shrink buffer, keep mem usage down buffer = new byte[remainBytes > INIT_BUF_SIZE ? remainBytes : INIT_BUF_SIZE]; } // consume bytes Buffer.BlockCopy(data, offset, buffer, 0, remainBytes); } else if (bytesReceived == data.Length) { // expand buffer buffer = new byte[bytesReceived * 2]; Buffer.BlockCopy(data, 0, buffer, 0, bytesReceived); } StartReceive(onReceivePacket); }); }); }
private async void ReadCallback(IAsyncResult ar) { if (_cancellationToken.IsCancellationRequested) { return; } int length; try { length = _socket.EndReceive(ar); } catch { await Disconnect(); return; } if (length == 0) { await Disconnect(); return; } var data = new byte[length + _extra.Length]; Array.Copy(_extra, 0, data, 0, _extra.Length); Array.Copy(_buffer, 0, data, _extra.Length, length); try { Packet packet; using (var ms = new MemoryStream(data)) { packet = ProtoBuf.Serializer.Deserialize <Packet>(ms); _extra = new byte[ms.Length - ms.Position]; ms.Read(_extra, 0, _extra.Length); } switch (packet) { case Ping p: await Send(Pong.Default); break; case Pong p: break; default: _logger?.LogDebug($"[Socket] {_socket.Handle} - Receive data: {Convert.ToBase64String(data)}"); OnReceivePacket?.Invoke(this, packet); break; } } catch (EndOfStreamException) { _extra = data; } catch (Exception) { await Disconnect(); } _waiterData.Release(); }
public void Subscribe(OnReceivePacket handler) { PacketSubscribers += handler; }