public void TotMessageTypeTest() { var x = TotMessageType.Notification; var x2 = TotMessageType.Ping; var x3 = new TotMessageType(); x3.FromHex("05"); var x4 = new TotMessageType(); x4.FromByte(5); Assert.NotEqual(x, x2); Assert.Equal(x, x3); Assert.Equal(x, x4); Assert.Equal("X'01'", TotMessageType.Request.ToHex(xhhSyntax: true)); Assert.Equal("02", TotMessageType.Response.ToHex(xhhSyntax: false)); Assert.Equal("03", TotMessageType.SubscribeRequest.ToHex()); Assert.Equal("X'05' Notification", TotMessageType.Notification.ToString()); Assert.Equal("X'06' Ping", TotMessageType.Ping.ToString()); Assert.Equal("X'07' Pong", TotMessageType.Pong.ToString()); var x6 = new TotMessageType(); x6.FromByte(8); Assert.Equal("X'08'", x6.ToString()); }
protected TotMessageBase(TotMessageType messageType, TotMessageId messageId, TotPurpose purpose, TotContent content) { Version = TotVersion.Version1; MessageType = Guard.NotNull(nameof(messageType), messageType); MessageId = Guard.NotNull(nameof(messageId), messageId); Purpose = purpose ?? TotPurpose.Empty; Content = content ?? TotContent.Empty; }
public override void FromBytes(byte[] bytes) { Guard.NotNullOrEmpty(nameof(bytes), bytes); Guard.InRangeAndNotNull($"{nameof(bytes)}.{nameof(bytes.Length)}", bytes.Length, 7, 536870912 + 3 + 4 + 255); Version = new TotVersion(); Version.FromByte(bytes[0]); MessageType = new TotMessageType(); MessageType.FromByte(bytes[1]); MessageId = new TotMessageId(); MessageId.FromBytes(bytes.Skip(2).Take(2).ToArray()); int purposeLength = bytes[4]; Purpose = new TotPurpose(); Purpose.FromBytes(bytes.Skip(4).Take(purposeLength + 1).ToArray(), startsWithLength: true); int contentLength = BitConverter.ToInt32(bytes.Skip(5 + purposeLength).Take(4).ToArray(), 0); Content = new TotContent(); Content.FromBytes(bytes.Skip(5 + purposeLength).ToArray(), startsWithLength: true); }
// async void is fine, because in case of exception it logs and it should not be awaited private async void ProcessMessageBytesAsync(byte[] bytes) { try { Guard.NotNull(nameof(bytes), bytes); var messageType = new TotMessageType(); messageType.FromByte(bytes[1]); if (messageType == TotMessageType.Pong) { var response = new TotPong(); response.FromBytes(bytes); ResponseCache.TryAdd(response.MessageId, response); } if (messageType == TotMessageType.Response) { var response = new TotResponse(); response.FromBytes(bytes); ResponseCache.TryAdd(response.MessageId, response); return; } var stream = TcpClient.GetStream(); var requestId = TotMessageId.Random; try { if (messageType == TotMessageType.Ping) { var request = new TotPing(); request.FromBytes(bytes); requestId = request.MessageId; AssertVersion(request.Version, TotVersion.Version1); var responseBytes = TotPong.Instance(request.MessageId).ToBytes(); await SendAsync(responseBytes).ConfigureAwait(false); return; } if (messageType == TotMessageType.Request) { var request = new TotRequest(); request.FromBytes(bytes); requestId = request.MessageId; AssertVersion(request.Version, TotVersion.Version1); OnRequestArrived(request); return; } } catch (TotRequestException) { await RespondVersionMismatchAsync(requestId).ConfigureAwait(false); throw; } catch { await SendAsync(new TotResponse(TotPurpose.BadRequest, new TotContent("Couldn't process the received message bytes."), requestId).ToBytes()).ConfigureAwait(false); throw; } } catch (Exception ex) { var exception = new TotRequestException("Couldn't process the received message bytes.", ex); Logger.LogWarning <TotClient>(exception, LogLevel.Debug); } }