/// <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); }
/// <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); } }
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); }