/// <summary> /// Sends a message to the server and then waits for the response to that message. /// </summary> /// <param name="message">The message to send.</param> /// <param name="replyTimeout">Time to wait for an answer.</param> /// <returns>The response message.</returns> public PooledMessage SendReceive(IMessage message, int replyTimeout = 0) { // Sanitize if (message?.Content == null) { throw new ArgumentNullException(nameof(message)); } if (replyTimeout == 0) { replyTimeout = _communicationTimeout; } if (!_isConnected) { return(null); } // Get the current thread ID int threadId = GetThreadId(); // Enroll in the multiplexer var multiplexerData = EnrollMultiplexer(threadId); var messageWithControlBytes = ProtocolHelper.AppendControlBytesToMessage(message, threadId); var socketAsyncEventArgs = _socketAsyncEventArgsSendPool.Pop(); socketAsyncEventArgs.SetBuffer(messageWithControlBytes.Content, 0, messageWithControlBytes.Length); socketAsyncEventArgs.UserToken = messageWithControlBytes; // Prioritize sends that have receives to the front of the queue _sendBufferQueue.EnqueueFront(socketAsyncEventArgs); // Wait for our message to go ahead from the receive callback, or until the timeout is reached if (!multiplexerData.ManualResetEventSlim.Wait(replyTimeout)) { // Timeout HandleCommunicationError(_socket, new TimeoutException("The connection timed out before the response message was received")); // Un-enroll from the multiplexer UnenrollMultiplexer(threadId); // tell message that it can return to the pool messageWithControlBytes?.Return(); // No signal return(null); } // Now get the command string var result = multiplexerData.Message; // Un-enroll from the multiplexer UnenrollMultiplexer(threadId); // tell message that it can return to the pool messageWithControlBytes?.Return(); return(result); }
/// <summary> /// Sends a message to the server and then waits for the response to that message. /// </summary> /// <param name="message">The message to send.</param> /// <returns>The response message.</returns> public byte[] SendReceive(byte[] message) { // Sanitize if (message == null) { throw new ArgumentNullException("message"); } // Get the current thread ID int threadId = Thread.CurrentThread.ManagedThreadId; int size; var socketAsyncEventArgs = _socketAsyncEventArgsSendPool.Pop(); if ((size = ProtocolHelper.AppendControlBytesToMessage(message, threadId, socketAsyncEventArgs.Buffer)) > 0) { socketAsyncEventArgs.SetBuffer(0, size); // Enroll in the multiplexer var multiplexerData = EnrollMultiplexer(threadId); // Prioritize sends that have receives to the front of the queue _sendBufferQueue.EnqueueFront(socketAsyncEventArgs); // Wait for our message to go ahead from the receive callback, or until the timeout is reached if (!multiplexerData.ManualResetEvent.WaitOne(_communicationTimeout)) { HandleCommunicationError(_socket, new TimeoutException("The connection timed out before the response message was received")); // Unenroll from the multiplexer UnenrollMultiplexer(threadId); // No signal return(null); } // Now get the command string var result = multiplexerData.Message; // Unenroll from the multiplexer UnenrollMultiplexer(threadId); return(result); } else { _socketAsyncEventArgsSendPool.Push(socketAsyncEventArgs); return(null); } }