/// <summary> /// Reads and decodes message from the stream from LOC server. /// </summary> /// <param name="CancellationToken">Cancallation token for async calls.</param> /// <param name="CheckProtocolViolation">If set to true, the function checks whether a protocol violation occurred and if so, it sends protocol violation error to the peer.</param> /// <returns>Received message of null if the function fails.</returns> public async Task <LocProtocolMessage> ReceiveMessageAsync(CancellationToken CancellationToken, bool CheckProtocolViolation = false) { log.Trace("()"); LocProtocolMessage res = null; RawMessageResult rawMessage = await messageReader.ReceiveMessageAsync(CancellationToken); if (rawMessage.Data != null) { res = (LocProtocolMessage)LocMessageBuilder.CreateMessageFromRawData(rawMessage.Data); } else { log.Debug("Connection to LOC server has been terminated."); } if (CheckProtocolViolation) { if ((res == null) || rawMessage.ProtocolViolation) { await messageProcessor.SendProtocolViolation(this); } } log.Trace("(-):{0}", res != null ? "LocProtocolMessage" : "null"); return(res); }
/// <summary> /// Reads messages from the client stream and processes them in a loop until the client disconnects /// or until an action (such as a protocol violation) that leads to disconnecting of the client occurs. /// </summary> /// <param name="Client">TCP client.</param> /// <param name="MessageBuilder">Client's message builder.</param> public async Task ReceiveMessageLoop(TcpClient Client, LocMessageBuilder MessageBuilder) { log.Trace("()"); try { NetworkStream stream = Client.GetStream(); RawMessageReader messageReader = new RawMessageReader(stream); while (!isShutdown) { RawMessageResult rawMessage = await messageReader.ReceiveMessageAsync(shutdownCancellationTokenSource.Token); bool disconnect = rawMessage.Data == null; bool protocolViolation = rawMessage.ProtocolViolation; if (rawMessage.Data != null) { LocProtocolMessage message = (LocProtocolMessage)LocMessageBuilder.CreateMessageFromRawData(rawMessage.Data); if (message != null) { disconnect = !await ProcessMessageAsync(Client, MessageBuilder, message); } else { protocolViolation = true; } } if (protocolViolation) { await SendProtocolViolation(Client); break; } if (disconnect) { break; } } } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } log.Trace("(-)"); }
/// <summary> /// Constructs ProtoBuf message from raw data read from the network stream. /// </summary> /// <param name="Data">Raw data to be decoded to the message.</param> /// <returns>ProtoBuf message or null if the data do not represent a valid message.</returns> public override IProtocolMessage CreateMessageFromRawData(byte[] Data) { return((IProtocolMessage)LocMessageBuilder.CreateMessageFromRawData(Data)); }