Beispiel #1
0
        public static PooledMessage Rent(int length)
        {
            var message = new PooledMessage
            {
                Content = ArrayPool.Rent(length),
                Length  = length,
                _rented = true
            };

            _rentCount++;
            return(message);
        }
Beispiel #2
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);
        }
Beispiel #3
0
        private void CompleteMessage(Socket handler, int threadId, PooledMessage receivedMessage)
        {
            receivedMessage.Socket = handler;
            //  receivedMessage.ConnectedClient = GetConnectedClient(handler);
            receivedMessage.ThreadId = threadId;

            // Fire the event if needed
            var messageReceived = MessageReceived;

            if (messageReceived != null)
            {
                // Create the message received args
                var messageReceivedArgs = _messageReceivedArgsPool.Pop();
                messageReceivedArgs.ReceivedMessage = receivedMessage;
                // Fire the event
                messageReceived(this, messageReceivedArgs);
                // Back in the pool
                _messageReceivedArgsPool.Push(messageReceivedArgs);
            }
        }
        private void CompleteMessage(Socket handler, int threadId, PooledMessage receivedMessage)
        {
            // Try and signal multiplexer
            var multiplexerData = GetMultiplexerData(threadId);

            if (multiplexerData != null)
            {
                multiplexerData.Message = receivedMessage;
                SignalMultiplexer(threadId);
                return;
            }

            // No multiplexer
            receivedMessage.Socket   = handler;
            receivedMessage.ThreadId = threadId;


            // Fire the event if needed
            var messageReceived = MessageReceived;

            if (messageReceived != null)
            {
                // Create the message received args
                var messageReceivedArgs = _messageReceivedArgsPool.Pop();
                messageReceivedArgs.ReceivedMessage = receivedMessage;
                // Fire the event
                messageReceived(this, messageReceivedArgs);
                // Back in the pool
                _messageReceivedArgsPool.Push(messageReceivedArgs);
            }
            else
            {
                // Return the message to the pool ourselves,
                // since there is nobody listening to the event to return it
                receivedMessage.Return();
            }
        }
        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);
            }
        }
Beispiel #6
0
 /// <summary>
 /// Sends a message back to the client.
 /// </summary>
 /// <param name="message">The reply message to send.</param>
 /// <param name="receivedMessage">The received message which is being replied to.</param>
 public void Reply(IMessage message, PooledMessage receivedMessage)
 {
     Send(message, receivedMessage.Socket, receivedMessage.ThreadId);
 }
Beispiel #7
0
 /// <summary>
 /// Sends a message back to the client.
 /// </summary>
 /// <param name="message">The reply message to send.</param>
 /// <param name="receivedMessage">The received message which is being replied to.</param>
 public void Reply(byte[] message, PooledMessage receivedMessage)
 {
     Reply(new Message(message), receivedMessage);
 }