public static PooledMessage Rent(int length) { var message = new PooledMessage { Content = ArrayPool.Rent(length), Length = length, _rented = true }; _rentCount++; return(message); }
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 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); } }
/// <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); }
/// <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); }