void ReadThreadV1() { while (true && !ReadBuffer.ShuttingDown) { if (Interlocked.Read(ref _disposed) == 1) { return; } Statistics.StartWaitRead(); ReadBuffer.Read((ptr) => { int readLength = 0; var header = FastStructure <RpcProtocolHeaderV1> .PtrToStructure(ptr); ptr = ptr + protocolLength; readLength += protocolLength; RpcRequest request = null; if (header.MsgType == MessageType.RpcResponse || header.MsgType == MessageType.ErrorInRpc) { if (!Requests.TryGetValue(header.ResponseId, out request)) { // The response received does not have a matching message that was sent Statistics.DiscardResponse(header.ResponseId); return(protocolLength); } } else { request = IncomingRequests.GetOrAdd(header.MsgId, new RpcRequest { MsgId = header.MsgId }); } int packetSize = header.PayloadSize < msgBufferLength ? header.PayloadSize : (header.CurrentPacket < header.TotalPackets ? msgBufferLength : header.PayloadSize % msgBufferLength); if (header.PayloadSize > 0) { if (request.Data == null) { request.Data = new byte[header.PayloadSize]; } int index = msgBufferLength * (header.CurrentPacket - 1); FastStructure.ReadBytes(request.Data, ptr, index, packetSize); readLength += packetSize; } if (header.CurrentPacket == header.TotalPackets) { if (header.MsgType == MessageType.RpcResponse || header.MsgType == MessageType.ErrorInRpc) { Requests.TryRemove(request.MsgId, out RpcRequest removed); } else { IncomingRequests.TryRemove(request.MsgId, out RpcRequest removed); } // Full message is ready var watching = Stopwatch.StartNew(); Task.Run(async() => { Statistics.MessageReceived(header.MsgType, request.Data?.Length ?? 0); if (header.MsgType == MessageType.RpcResponse) { request.IsSuccess = true; request.ResponseReady.Set(); } else if (header.MsgType == MessageType.ErrorInRpc) { request.IsSuccess = false; request.ResponseReady.Set(); } else if (header.MsgType == MessageType.RpcRequest) { await ProcessCallHandler(request).ConfigureAwait(false); } }); } Statistics.ReadPacket(packetSize); return(protocolLength + packetSize); }, 500); } }
async Task <RpcResponse> SendMessage(RpcRequest request, byte[] payload, int timeout = defaultTimeoutMs) { return(await SendMessage(MessageType.RpcRequest, request, payload, timeout : timeout).ConfigureAwait(false)); }