예제 #1
0
        /// <summary>
        /// Sends a message to the server without waiting for a response (one-way communication).
        /// </summary>
        /// <param name="message">The message to send.</param>
        public void Send(IMessage message)
        {
            // Sanitize
            if (message?.Content == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (!_isConnected)
            {
                return;
            }

            // Get the current thread ID
            var threadId = GetThreadId();

            var messageWithControlBytes = ProtocolHelper.AppendControlBytesToMessage(message, threadId);
            var socketAsyncEventArgs    = _socketAsyncEventArgsSendPool.Pop();

            socketAsyncEventArgs.SetBuffer(messageWithControlBytes.Content, 0, messageWithControlBytes.Length);
            socketAsyncEventArgs.UserToken = messageWithControlBytes;

            _sendBufferQueue.Enqueue(socketAsyncEventArgs);
        }
예제 #2
0
        /// <summary>
        /// Sends a message to the server without waiting for a response (one-way communication).
        /// </summary>
        /// <param name="message">The message to send.</param>
        public void Send(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);
                _sendBufferQueue.Enqueue(socketAsyncEventArgs);
            }
            else
            {
                _socketAsyncEventArgsSendPool.Push(socketAsyncEventArgs);
            }
        }
예제 #3
0
        private void ReceiveCallback(Socket socket, SocketAsyncEventArgs socketAsyncEventArgs)
        {
            // Check for error
            if (socketAsyncEventArgs.SocketError != SocketError.Success)
            {
                (socketAsyncEventArgs.UserToken as PooledMessage)?.Dispose();
                HandleCommunicationError(socket, new Exception("Receive failed, error = " + socketAsyncEventArgs.SocketError));
            }

            // Get the message state
            int bytesRead = socketAsyncEventArgs.BytesTransferred;

            // Read the data
            if (bytesRead > 0)
            {
                // Add to receive queue
                BlockingQueue <SocketAsyncEventArgs> receiveBufferQueue = null;
                _currentlyConnectedClientsReceiveQueuesLock.EnterReadLock();
                try
                {
                    if (!_currentlyConnectedClientsReceiveQueues.TryGetValue(socket, out receiveBufferQueue))
                    {
                        // Peace out!
                        return;
                    }
                }
                finally
                {
                    _currentlyConnectedClientsReceiveQueuesLock.ExitReadLock();
                }

                receiveBufferQueue.Enqueue(socketAsyncEventArgs);
            }
            else
            {
                // 0 bytes means disconnect
                (socketAsyncEventArgs.UserToken as PooledMessage)?.Dispose();
                HandleCommunicationError(socket, new Exception("Received 0 bytes (graceful disconnect)"));

                _socketAsyncEventArgsReceivePool.Push(socketAsyncEventArgs);
                return;
            }

            socketAsyncEventArgs = _socketAsyncEventArgsReceivePool.Pop();

            // Post a receive to the socket as the client will be continuously receiving messages to be pushed to the queue
            TryUnsafeSocketOperation(socket, SocketAsyncOperation.Receive, socketAsyncEventArgs);
        }