コード例 #1
0
ファイル: Connection.cs プロジェクト: cshung/MultiplexingLab
            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;
            }
コード例 #2
0
ファイル: Connection.cs プロジェクト: cshung/MultiplexingLab
 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;
 }