private ActorContinuation OnTransportReadCompletionMessage(TransportReadCompletionMessage transportReadCompletionMessage) { int bytesRead = transportReadCompletionMessage.BytesRead; int decodingBufferStart = this.bufferStart; int decodingBufferSize = bytesRead; int decodingPointer = decodingBufferStart; int sizeRemaining = decodingBufferSize; // Buffering the decoded payload so that we don't notify receiver before we are done with the parsing Dictionary<int, List<ArraySegment<byte>>> decodedPayloadLists = new Dictionary<int, List<ArraySegment<byte>>>(); while (sizeRemaining > 0) { if (this.decodingState.LastFrameHeaderIncomplete) { this.decodingState.LastFrameHeaderIncomplete = false; while (this.decodingState.LastIncompleteHeader.Count < Constants.HeaderSize && sizeRemaining > 0) { this.decodingState.LastIncompleteHeader.Add(this.buffer[decodingPointer]); decodingPointer++; sizeRemaining--; } if (this.decodingState.LastIncompleteHeader.Count == Constants.HeaderSize) { FrameHeader header = FrameHeader.Decode(this.decodingState.LastIncompleteHeader); int consumed = this.DecodePayload(decodingPointer, sizeRemaining, header, decodedPayloadLists); decodingPointer += consumed; sizeRemaining -= consumed; } else { this.decodingState.LastFrameHeaderIncomplete = true; } } else if (this.decodingState.LastFramePayloadIncomplete) { this.decodingState.LastFramePayloadIncomplete = false; int consumed = this.DecodePayload(decodingPointer, sizeRemaining, this.decodingState.LastIncompletePayloadHeader, decodedPayloadLists); decodingPointer += consumed; sizeRemaining -= consumed; } else { // Can I grab the whole header? if (sizeRemaining >= Constants.HeaderSize) { FrameHeader header = FrameHeader.Decode(new ArraySegment<byte>(this.buffer, decodingPointer, Constants.HeaderSize)); decodingPointer += Constants.HeaderSize; sizeRemaining -= Constants.HeaderSize; int consumed = this.DecodePayload(decodingPointer, sizeRemaining, header, decodedPayloadLists); decodingPointer += consumed; sizeRemaining -= consumed; } else { this.decodingState.LastFrameHeaderIncomplete = true; this.decodingState.LastIncompleteHeader = new List<byte>(); while (sizeRemaining > 0) { this.decodingState.LastIncompleteHeader.Add(this.buffer[decodingPointer]); decodingPointer++; sizeRemaining--; } } } } foreach (KeyValuePair<int, List<ArraySegment<byte>>> decodedPayloadList in decodedPayloadLists) { int channelId = decodedPayloadList.Key; ChannelReceivingActor channelReceivingActor; if (!this.channelReceivingActors.TryGetValue(channelId, out channelReceivingActor)) { channelReceivingActor = new ChannelReceivingActor(this, this.ActorManager); this.ActorManager.RunActor(channelReceivingActor); this.channelReceivingActors.Add(channelId, channelReceivingActor); this.pendingAcceptChannels.Enqueue(new Channel(this.parent, channelId)); this.TrySatisfyAcceptRequest(); } // Book keeping the amount of data held unread this.unreadBytes += decodedPayloadList.Value.Select(t => t.Count).Sum(); this.Send(channelReceivingActor, new DataArrivedMessage(decodedPayloadList.Value)); } if (bytesRead == 0) { // The other side closed the connection // TODO: Handle the connection close situation return ActorContinuation.BlockOnReceive; } if (this.bufferStart + bytesRead < Constants.BufferSize) { this.bufferStart = this.bufferStart + bytesRead; this.parent.TransportRead(this.buffer, this.bufferStart); } else { this.bufferFull = true; this.TryReuseBuffer(); } return ActorContinuation.BlockOnReceive; }
private ActorContinuation OnChannelCreatedMessage(ChannelCreatedMessage channelCreatedMessage) { ChannelReceivingActor channelReceivingActor = new ChannelReceivingActor(this, this.ActorManager); this.channelReceivingActors.Add(channelCreatedMessage.ChannelId, channelReceivingActor); this.ActorManager.RunActor(channelReceivingActor); return ActorContinuation.BlockOnReceive; }