Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
            }
        }