private async Task <TotMessageBase> ReceiveAsync(TotMessageId expectedMessageId, TotVersion expectedVersion, int timeout) { Guard.NotNull(nameof(expectedMessageId), expectedMessageId); Guard.NotNull(nameof(expectedVersion), expectedVersion); Guard.MinimumAndNotNull(nameof(timeout), timeout, 1); int delay = 10; int maxDelayCount = timeout / delay; int delayCount = 0; while (!ResponseCache.ContainsKey(expectedMessageId)) { if (delayCount > maxDelayCount) { throw new TimeoutException($"No response arrived within the specified timeout: {timeout} milliseconds."); } await Task.Delay(delay).ConfigureAwait(false); delayCount++; } ResponseCache.TryRemove(expectedMessageId, out TotMessageBase response); AssertVersion(expectedVersion, response.Version); return(response); }
public async Task RespondSuccessAsync(TotMessageId messageId) { Guard.NotNull(nameof(messageId), messageId); var response = new TotResponse(TotPurpose.Success, messageId); await SendAsync(response.ToBytes()).ConfigureAwait(false); }
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; }
/// <summary> /// The server was not able to execute the Request properly. /// </summary> public async Task RespondUnsuccessfulRequestAsync(TotMessageId messageId, string errorContent = "") { Guard.NotNull(nameof(messageId), messageId); var response = new TotResponse(TotPurpose.UnsuccessfulRequest, messageId); if (!string.IsNullOrWhiteSpace(errorContent)) { response.Content = new TotContent(errorContent); } await SendAsync(response.ToBytes()).ConfigureAwait(false); }
/// <param name="purpose">Success, BadRequest, VersionMismatch, UnsuccessfulRequest</param> public TotResponse(TotPurpose purpose, TotContent content, TotMessageId messageId) : base(TotMessageType.Response, messageId, purpose, content) { Guard.NotNull(nameof(purpose), purpose); if (purpose != TotPurpose.Success && purpose != TotPurpose.BadRequest && purpose != TotPurpose.VersionMismatch && purpose != TotPurpose.UnsuccessfulRequest) { throw new ArgumentException($"{nameof(purpose)} of {nameof(TotResponse)} can only be {TotPurpose.Success}, {TotPurpose.BadRequest}, {TotPurpose.VersionMismatch} or {TotPurpose.UnsuccessfulRequest}. Actual: {purpose}."); } }
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); }
public TotPong(TotContent content, TotMessageId messageId) : base(TotMessageType.Pong, messageId, TotPurpose.Pong, content) { }
public static TotPong Instance(TotMessageId messageId) => new TotPong(TotContent.Empty, messageId);
private async Task RespondVersionMismatchAsync(TotMessageId messageId) { Guard.NotNull(nameof(messageId), messageId); await SendAsync(TotResponse.VersionMismatch(messageId).ToBytes()).ConfigureAwait(false); }
/// <param name="purpose">Success, BadRequest, VersionMismatch, UnsuccessfulRequest</param> public TotResponse(TotPurpose purpose, TotMessageId messageId) : this(purpose, TotContent.Empty, messageId) { }
/// <summary> /// The server was not able to execute the Request properly. UnsuccessfulReqeust SHOULD be issued in case of server side errors. /// </summary> public static TotResponse UnsuccessfulRequest(TotMessageId messageId) => new TotResponse(TotPurpose.UnsuccessfulRequest, messageId);
public static TotResponse VersionMismatch(TotMessageId messageId) => new TotResponse(TotPurpose.VersionMismatch, messageId);
/// <summary> /// The request was malformed. BadRequest SHOULD be issued in case of client side errors. /// </summary> public static TotResponse BadRequest(TotMessageId messageId) => new TotResponse(TotPurpose.BadRequest, messageId);
public static TotResponse Success(TotMessageId messageId) => new TotResponse(TotPurpose.Success, messageId);