/// <summary> /// Callback routine for handling send completes. /// </summary> /// <param name="result">The result of the asynchronous operation.</param> static private void EventSendComplete(IAsyncResult result) { // Get the subscriber object as context for this request. IProcEventSubscriber sub = null; try { sub = ( IProcEventSubscriber )result.AsyncState; sub.eventSocket.EndSend(result); } catch (Exception e) { log.Error(e, String.Format("{0} : Error in send complete.", sub.port)); } }
/// <summary> /// Event registration service. /// </summary> private void RegistrationService() { bool exitLoop = false; while (!exitLoop) { try { // Wait for an incoming request. Socket clientSocket = regSocket.Accept(); try { // Make sure that this request came from the loopback address. Off-box requests are not supported. if (IPAddress.IsLoopback((clientSocket.RemoteEndPoint as IPEndPoint).Address)) { // Setup an asynchronous receive so all requests get processed in a different execution thread. IProcEventSubscriber sub = new IProcEventSubscriber(clientSocket); clientSocket.BeginReceive(sub.ReceiveBuffer, 0, sub.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(IProcEventSubscriber.MessageHandler), sub); } else { clientSocket.Close(); } } catch (SocketException e) { log.Error(e, "Socket exception"); } catch (Exception e) { log.Error(e, "Cannot begin message processing due to unknown exception."); clientSocket.Close(); } } catch (SocketException e) { exitLoop = true; log.Debug(e, "Error socket exception. Exiting loop."); } catch (Exception e) { // Stay in the loop until the socket is closed. log.Debug(e, "Error exception."); } } }
/// <summary> /// Processes incoming messages intended for this subscriber. /// </summary> /// <param name="result">The result of the asynchronous operation.</param> static internal void MessageHandler(IAsyncResult result) { // Get the subscriber object as context for this request. IProcEventSubscriber sub = ( IProcEventSubscriber )result.AsyncState; try { // End the pending read operation. int bytesReceived = sub.eventSocket.EndReceive(result); if (bytesReceived > 0) { try { // Keep track of how much data is in the buffer. sub.bufferLength += bytesReceived; int bytesToProcess = sub.bufferLength; int msgIndex = 0; // Process as much as is available. while (bytesToProcess > 0) { // There needs to be atleast 4 bytes for the message length. if (bytesToProcess >= 4) { // Get the length of the message, add in the prepended length. int msgLength = BitConverter.ToInt32(sub.receiveBuffer, msgIndex) + 4; // See if the entire message is represented in the buffer. if (bytesToProcess >= msgLength) { // Process the message received from the client. Skip the message length. sub.ProcessMessage(new ASCIIEncoding().GetString(sub.receiveBuffer, msgIndex + 4, msgLength - 4)); msgIndex += msgLength; bytesToProcess -= msgLength; } else { break; } } else { break; } } // Update how much data is left in the buffer. sub.bufferLength = bytesToProcess; // If any data has been processed at the beginning of the buffer, the unprocessed // data needs to be moved to the front. if ((bytesToProcess > 0) && (msgIndex > 0)) { // Move any existing data up. Buffer.BlockCopy(sub.receiveBuffer, msgIndex, sub.receiveBuffer, 0, bytesToProcess); } } catch (Exception e) { log.Error(e, "{0} : Error processing event message from client.", sub.port); } // Repost the buffer. sub.eventSocket.BeginReceive(sub.receiveBuffer, sub.bufferLength, sub.receiveBuffer.Length - sub.bufferLength, SocketFlags.None, new AsyncCallback(MessageHandler), sub); } else { // The client is going away. Clean up his events. log.Debug("Client {0} has terminated the connection.", (sub.eventSocket.RemoteEndPoint as IPEndPoint).Address); sub.DisposeSubscribers(); sub.eventSocket.Shutdown(SocketShutdown.Both); sub.eventSocket.Close(); IProcEventSubscriber.subscriberTable.Remove(sub.port); } } catch (SocketException e) { log.Error(e, "{0} : Error communication failure.", sub.port); IProcEventSubscriber.subscriberTable.Remove(sub.port); } catch (Exception e) { log.Error(e, "{0} : Error exception occurred.", sub.port); IProcEventSubscriber.subscriberTable.Remove(sub.port); } }