/// <summary> /// Register and subscribe to packet receive event /// </summary> /// <param name="onReceive">event that will be called when packet deserialized with ReadPacket method</param> /// <param name="packetConstructor">Method that constructs packet intead of slow Activator.CreateInstance</param> /// <exception cref="InvalidTypeException"><typeparamref name="T"/>'s fields are not supported, or it has no fields</exception> public void Subscribe <T>(Action <T> onReceive, Func <T> packetConstructor) where T : class, new() { //_netSerializer.Register<T>(); _callbacks[GetHash(typeof(T))] = (reader, userData) => { //var reference = packetConstructor(); long bytesRead; var reference = _netSerializer.Deserialize <T>(reader.RawData, reader.UserDataOffset + 8, reader.RawDataSize, out bytesRead); pos += bytesRead; onReceive(reference); }; }
protected override void Test(FTestMessage message, Action <FTestMessage> customAssert = null) { var serialized = ProtoSerializer.Serialize(message); var deserialized = ProtoSerializer.Deserialize <FTestMessage>(serialized); AssertDeserialized(message, deserialized, customAssert); }
protected override void Test(FTestMessage message, Action <FTestMessage> customAssert = null) { using (var pool = ProtoSerializer.SerializePooled(message)) { var buf = pool.Item; var deserialized = ProtoSerializer.Deserialize <FTestMessage>(buf.Buffer, buf.Offset, buf.Count); AssertDeserialized(message, deserialized, customAssert); } }
protected override void Test(FTestMessage message, Action <FTestMessage> customAssert = null) { using (var ms = new MemoryStream()) { ProtoSerializer.Serialize(ms, message); ms.Position = 0; var deserialized = (FTestMessage)ProtoSerializer.Deserialize(typeof(FTestMessage), ms); AssertDeserialized(message, deserialized, customAssert); } }
private void LoadSettings() { if (!File.Exists(PathManager.SettingsFileName)) { Settings = new Settings(); } else { try { var data = File.ReadAllBytes(PathManager.SettingsFileName); Settings = ProtoSerializer.Deserialize <Settings>(data) ?? new Settings(); } catch (Exception ex) { AppLogger.Error(ex, "Failed load settings."); } } }
private void SendDataAsync() { uint sequenceId = 0; while (true) { if (sequenceId == 0) { sequenceId = this.session.GetResendSequenceAsync(); } if (sequenceId == 0) { try { this.WaitForSendWindowAsync(this.session.Context); } catch (Exception e) { if (e == Constants.MaxWaitError) { continue; } throw e; } var nextSendSequenceId = this.session.GetSendSequenceAsync(); sequenceId = nextSendSequenceId.Value; } var data = this.session.GetDataToSend(sequenceId); if (data == null) { this.sequencesSentTimes.Remove(sequenceId); this.sequencesResentTimes.Remove(sequenceId); sequenceId = 0; continue; } try { var packet = ProtoSerializer.Deserialize <Packet>(data); if (packet.SequenceId != sequenceId) { throw new Exception("sequence missmatch"); } Console.WriteLine($"Sending session message. Packet Id: {sequenceId}, Data Length: {packet.Data.Length}, Data: {string.Join(", ", packet.Data.Take(10))}"); this.session.SendDataAsync(this.LocalClientId, this.RemoteClientId, data); } catch (Exception e) { if (this.session.IsClosed) { throw new SessionClosedException(); } var cts = new CancellationTokenSource(); var channelTasks = new List <Task <Channel <uint?> > > { this.session.ResendChannel.Push(sequenceId, cts.Token), this.session.Context.DoneChannel.Shift(cts.Token) }; var channel = channelTasks.FirstAsync(cts); if (channel == this.session.ResendChannel) { sequenceId = 0; break; } else if (channel == this.session.Context.DoneChannel) { throw this.session.Context.Error; } Thread.Sleep(1000); continue; } if (this.sequencesSentTimes.ContainsKey(sequenceId) == false) { this.sequencesSentTimes.Add(sequenceId, DateTime.Now); } this.sequencesResentTimes.Remove(sequenceId); sequenceId = 0; } }
private async Task <bool> HandleInboundMessageAsync(byte[] data) { var inboundMessage = ProtoSerializer.Deserialize <InboundMessage>(data); if (inboundMessage.PreviousSignature?.Length > 0) { var previousSignatureHex = inboundMessage.PreviousSignature.ToHexString(); var receipt = MessageFactory.MakeReceipt(this.key, previousSignatureHex); var receiptBytes = receipt.ToBytes(); this.SendThroughSocket(receiptBytes); } var messagePayload = ProtoSerializer.Deserialize <MessagePayload>(inboundMessage.Payload); var payloadBytes = this.GetPayload(messagePayload, inboundMessage.Source); var payload = ProtoSerializer.Deserialize <Payload>(payloadBytes); string textMessage = null; switch (payload.Type) { case PayloadType.Binary: break; case PayloadType.Text: var textData = ProtoSerializer.Deserialize <TextDataPayload>(payload.Data); textMessage = textData.Text; break; case PayloadType.Ack: this.textResponseManager.ProcessResponse(payload.ReplyToId, null, payload.Type); this.binaryResponseManager.ProcessResponse(payload.ReplyToId, null, payload.Type); return(true); case PayloadType.Session: break; default: break; } if (payload.ReplyToId?.Length > 0) { if (textMessage == null) { this.binaryResponseManager.ProcessResponse(payload.ReplyToId, payload.Data, payload.Type); } else { this.textResponseManager.ProcessResponse(payload.ReplyToId, textMessage, payload.Type); } return(true); } var responses = Enumerable.Empty <object>(); switch (payload.Type) { case PayloadType.Binary: case PayloadType.Session: case PayloadType.Text: var request = new MessageHandlerRequest { Source = inboundMessage.Source, Payload = payload.Data, PayloadType = payload.Type, IsEncrypted = messagePayload.IsEncrypted, MessageId = payload.MessageId, NoReply = payload.NoReply, TextMessage = textMessage }; var tasks = this.messageHandlers.Select(async func => { try { return(await func(request)); } catch (Exception) { return(null); } }); responses = await Task.WhenAll(tasks); break; case PayloadType.Ack: break; } if (payload.NoReply == false) { var responded = false; foreach (var response in responses) { if (response is bool res) { if (res == false) { return(true); } } else if (response != null) { if (response is byte[] bytes) { this.SendDataAsync <byte[]>(inboundMessage.Source, bytes, new SendOptions { IsEncrypted = messagePayload.IsEncrypted, ReplyToId = payload.MessageId.ToHexString() }); responded = true; break; } else if (response is string text) { this.SendTextAsync <string>(inboundMessage.Source, text, new SendOptions { IsEncrypted = messagePayload.IsEncrypted, ReplyToId = payload.MessageId.ToHexString() }); responded = true; break; } } } if (responded == false) { this.SendAck(inboundMessage.Source, payload.MessageId, messagePayload.IsEncrypted); } } return(true); }
private void addTestModel(byte[] model) => data.Add(ProtoSerializer.Deserialize <TestModel>(model));
public async Task ReceiveWithClientAsync(string localClientId, string remoteClientId, byte[] buffer) { if (this.IsClosed) { throw new SessionClosedException(); } var packet = ProtoSerializer.Deserialize <Packet>(buffer); if (packet.Data != null) { Console.WriteLine($"Receiving session message. Packet Id: {packet.SequenceId}, Data Lengtht: {packet.Data?.Length}, Data: {(packet.Data == null ? string.Empty : string.Join(", ", packet.Data.Take(10)))}"); } if (packet.IsClose) { this.HandleClosePacket(); return; } var established = this.isEstablished; if (established == false && packet.IsHandshake) { this.HandleHandshakePacketAsync(packet); return; } if (established && (packet.AckStartSeqs?.Length > 0 || packet.AckSeqCounts?.Length > 0)) { if (packet.AckSeqCounts?.Length > 0 && packet.AckStartSeqs?.Length > 0 && packet.AckStartSeqs?.Length != packet.AckSeqCounts?.Length) { throw new InvalidPacketException("AckStartSeq and AckSeqCount should have the same length if both are non-empty"); } int count; if (packet.AckStartSeqs.Length > 0) { count = packet.AckStartSeqs.Length; } else { count = packet.AckSeqCounts.Length; } uint ackStartSequenceId; uint ackEndSequenceId; for (int i = 0; i < count; i++) { if (packet.AckStartSeqs.Length > 0) { ackStartSequenceId = packet.AckStartSeqs[i]; } else { ackStartSequenceId = Constants.MinSequenceId; } if (packet.AckSeqCounts?.Length > 0) { var step = (int)packet.AckSeqCounts[i]; ackEndSequenceId = Session.NextSequenceId(ackStartSequenceId, step); } else { ackEndSequenceId = Session.NextSequenceId(ackStartSequenceId); } var nextSequenceAvailable = Session.IsSequenceInbetween( this.sendWindowStartSequenceId, this.sendWindowEndSequenceId, Session.NextSequenceId(ackEndSequenceId, -Session.DefaultStepSize)); if (nextSequenceAvailable) { var ackIsInBounds = Session.IsSequenceInbetween( this.sendWindowStartSequenceId, this.sendWindowEndSequenceId, ackStartSequenceId); if (ackIsInBounds == false) { ackStartSequenceId = this.sendWindowStartSequenceId; } for ( var currentSequenceId = ackStartSequenceId; Session.IsSequenceInbetween(ackStartSequenceId, ackEndSequenceId, currentSequenceId); currentSequenceId = Session.NextSequenceId(currentSequenceId)) { foreach (var connection in this.connections) { var isSentByMe = connection.Key == Connection.GetKey(localClientId, remoteClientId); connection.Value.ReceiveAck(currentSequenceId, isSentByMe); } this.sendWindowData.Remove(currentSequenceId); } if (ackStartSequenceId == this.sendWindowStartSequenceId) { while (true) { this.sendWindowStartSequenceId = Session.NextSequenceId(this.sendWindowStartSequenceId); if (this.sendWindowData.ContainsKey(this.sendWindowStartSequenceId)) { break; } if (this.sendWindowStartSequenceId == this.sendWindowEndSequenceId) { break; } } } } } } if (established && packet.BytesRead > this.remoteBytesRead) { this.remoteBytesRead = packet.BytesRead; var cts = new CancellationTokenSource(); var channelTasks = new List <Task <Channel <uint?> > > { this.sendWindowUpdateChannel.Push(null, cts.Token), Constants.ClosedChannel.Shift(cts.Token) }; await channelTasks.FirstAsync(cts); } if (established && packet.SequenceId > 0) { if (packet.Data.Length > this.recieveMtu) { throw new DataSizeTooLargeException(); } if (Session.CompareSequenceIds(packet.SequenceId, this.receiveWindowStartSeq) >= 0) { if (this.receiveWindowData.ContainsKey(packet.SequenceId) == false) { if (this.receiveWindowUsed + packet.Data.Length > this.receiveWindowSize) { throw new RecieveWindowFullException(); } this.receiveWindowData.TryAdd(packet.SequenceId, packet.Data); this.receiveWindowUsed += packet.Data.Length; if (packet.SequenceId == this.receiveWindowStartSeq) { var cts2 = new CancellationTokenSource(); var channelTasks2 = new List <Task <Channel <uint?> > > { this.recieveDataUpdateChannel.Push(null, cts2.Token), Constants.ClosedChannel.Shift(cts2.Token) }; await channelTasks2.FirstAsync(cts2); } } } var connectionKey = Connection.GetKey(localClientId, remoteClientId); if (this.connections.ContainsKey(connectionKey)) { var conn = this.connections[connectionKey]; conn.SendAck(packet.SequenceId); } } }
public static T FromBytes <T>(this byte[] data) where T : class, ISerializable { return(ProtoSerializer.Deserialize <T>(data)); }