Example #1
0
        public static PooledMessage AppendControlBytesToMessage(IMessage message, int threadId)
        {
            // Create room for the control bytes
            var messageWithControlBytes = PooledMessage.Rent(ControlBytesPlaceholder.Length + message.Length);

            // Tell messageWithControlBytes that it can be returned to the pool after it has been send
            messageWithControlBytes.ReturnAfterSend();
            // Copy data to message with control bytes
            Buffer.BlockCopy(message.Content, 0, messageWithControlBytes.Content, ControlBytesPlaceholder.Length, message.Length);
            // Set the control bytes on the message
            SetControlBytes(messageWithControlBytes.Content, message.Length, threadId);
            // Tell message it has been sent. It may decide to return to pool
            message.Sent();
            return(messageWithControlBytes);
        }
        private void ProcessReceivedMessage(Socket handler)
        {
            int bytesToRead = -1;
            int threadId    = -1;

            int controlBytesOffset = 0;

            byte[]        protocolBuffer = new byte[ProtocolHelper.ControlBytesPlaceholder.Length];
            PooledMessage resultBuffer   = null;

            // Loop until socket is done
            while (_isConnected)
            {
                // Get the next buffer from the queue
                var socketAsyncEventArgs = _receiveBufferQueue.Dequeue();
                if (socketAsyncEventArgs == null)
                {
                    continue;
                }

                var buffer    = socketAsyncEventArgs.Buffer;
                int bytesRead = socketAsyncEventArgs.BytesTransferred;

                int currentOffset = 0;

                while (currentOffset < bytesRead)
                {
                    // Check if we need to get our control byte values
                    if (bytesToRead == -1)
                    {
                        var controlBytesNeeded    = ProtocolHelper.ControlBytesPlaceholder.Length - controlBytesOffset;
                        var controlBytesAvailable = bytesRead - currentOffset;

                        var controlBytesToCopy = Math.Min(controlBytesNeeded, controlBytesAvailable);

                        // Copy bytes to control buffer
                        Buffer.BlockCopy(buffer, currentOffset, protocolBuffer, controlBytesOffset, controlBytesToCopy);

                        controlBytesOffset += controlBytesToCopy;
                        currentOffset      += controlBytesToCopy;

                        // Check if done
                        if (controlBytesOffset == ProtocolHelper.ControlBytesPlaceholder.Length)
                        {
                            // Parse out control bytes
                            ProtocolHelper.ExtractControlBytes(protocolBuffer, out bytesToRead, out threadId);

                            // Reset control bytes offset
                            controlBytesOffset = 0;

                            // Ensure message is not larger than maximum message size
                            if (bytesToRead > _maxMessageSize)
                            {
                                HandleCommunicationError(handler, new InvalidOperationException(string.Format("message of length {0} exceeds maximum message length of {1}", bytesToRead, _maxMessageSize)));
                                return;
                            }
                        }

                        // Continue the loop
                        continue;
                    }

                    // Have control bytes, get message bytes

                    // SPECIAL CASE: if empty message, skip a bunch of stuff
                    if (bytesToRead != 0)
                    {
                        // Initialize buffer if needed
                        if (resultBuffer == null)
                        {
                            //resultBuffer = new byte[bytesToRead]
                            resultBuffer = PooledMessage.Rent(bytesToRead);
                        }

                        var bytesAvailable = bytesRead - currentOffset;
                        var bytesToCopy    = Math.Min(bytesToRead, bytesAvailable);

                        // Copy bytes to buffer
                        Buffer.BlockCopy(buffer, currentOffset, resultBuffer.Content, resultBuffer.Length - bytesToRead, bytesToCopy);

                        currentOffset += bytesToCopy;
                        bytesToRead   -= bytesToCopy;
                    }

                    // Check if we're done
                    if (bytesToRead == 0)
                    {
                        if (resultBuffer != null)
                        {
                            // Done, add to complete received messages
                            CompleteMessage(handler, threadId, resultBuffer);

                            // Reset message state
                            resultBuffer = null;
                        }

                        bytesToRead = -1;
                        threadId    = -1;

                        _lastResponse = DateTime.UtcNow;
                    }
                }

                _socketAsyncEventArgsReceivePool.Push(socketAsyncEventArgs);
            }
        }