protected void DeserializePacket(Type packetType, bool compressed, int size, MessageBuffer packetBuffer) { // Invoke the following generic method here to enable AOT // public static T Deserialize<T>(ReadOnlyMemory<byte> buffer, MessagePackSerializerOptions options = null, CancellationToken cancellationToken = default); MethodInfo genericDeserializeMethod; if (!_GenericDeserializeMethods.TryGetValue(packetType, out genericDeserializeMethod)) { genericDeserializeMethod = DeserializeMethod.MakeGenericMethod(packetType); _GenericDeserializeMethods[packetType] = genericDeserializeMethod; } try { var memory = new ReadOnlyMemory <byte>(packetBuffer.Data(), packetBuffer.Rpos(), size); _parameterCache.Value[0] = memory; _parameterCache.Value[1] = compressed ? NetSettings.LZ4CompressOptions : NetSettings.MessagePackOptions; var obj = genericDeserializeMethod.Invoke(null, _parameterCache.Value); if (Session != null) { Session.QueuePacket(obj as ObjectPacket); } } catch { if (LogException) { var message = string.Format("Client {0} sent malformed packet (size: {1}, packetType: {2}).", RemoteAddress, size, packetType); if (NetSettings.Logger != null) { NetSettings.Logger.Warn(message); } else { Console.WriteLine(message); } } if (CloseOnMalformedPacket) { CloseSocket(); return; } else { // Buffer are corrupted, reset! packetBuffer.Reset(); return; } } packetBuffer.ReadCompleted(size); }
protected override void ReadHandler() { MessageBuffer buffer = GetReadBuffer(); while (buffer.GetActiveSize() > 0) { int size = RecvHeaderSize; if (buffer.GetActiveSize() < size) { break; } // We just received nice new header if (!_NextPacketDecrypted) { _authCrypt.DecryptRecv(buffer.Data(), buffer.Rpos(), size); } _NextPacketDecrypted = false; var addr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Data(), buffer.Rpos()); int packetId; bool compressed; if (ServerSocket) { var header = Marshal.PtrToStructure <ClientPacketHeader>(addr); size = header.Size + sizeof(ushort); packetId = header.PacketId; compressed = header.Compressed != 0; } else { var header = Marshal.PtrToStructure <ServerPacketHeader>(addr); size = header.Size + sizeof(int); packetId = header.PacketId; compressed = header.Compressed != 0; } var packetType = ObjectPacket.GetPacketType(packetId); if (packetType == null || size <= 0 || size >= _MaxPacketSize) { if (LogException) { var message = string.Format("Client {0} sent malformed packet (size: {1}, packetId: {2}).", RemoteAddress, size, packetId); if (NetSettings.Logger != null) { NetSettings.Logger.Warn(message); } else { Console.WriteLine(message); } } if (CloseOnMalformedPacket) { CloseSocket(); return; } else { // Buffer are corrupted, reset! buffer.Reset(); continue; } } if (buffer.GetActiveSize() < size) { // NOTE: The header buffer of next upcoming packet is already decrypted in above code. // We must skip _authCrypt.DecryptRecv() for next packet. _NextPacketDecrypted = true; break; } buffer.ReadCompleted(RecvHeaderSize); size -= RecvHeaderSize; DeserializePacket(packetType, compressed, size, buffer); } AsyncRead(); }
private void WriteHandlerInternal(IAsyncResult result) { switch (_error) { case SocketError.Success: case SocketError.IOPending: break; default: CloseSocket(); return; } try { var transferedBytes = _socket.EndSend(result); TotalBytesSent += transferedBytes; MessageBuffer buffer = null; if (!_writeQueue.TryPeek(out buffer)) { throw new ApplicationException("BaseSocket: _writeQueue.TryPeek() failed, which is impossible!"); } buffer.ReadCompleted(transferedBytes); if (buffer.GetActiveSize() <= 0) { if (!_writeQueue.TryDequeue(out buffer)) { throw new ApplicationException("BaseSocket: _writeQueue.TryDequeue() failed, which is impossible!"); } } _isWritingAsync.Exchange(false); if (!_writeQueue.IsEmpty) { AsyncProcessQueue(); } else if (_closing) { CloseSocket(); } } catch (Exception ex) { CloseSocket(); if (LogException) { if (NetSettings.Logger != null) { NetSettings.Logger.Warn(ex); } else { Console.WriteLine(ex); } } } }