/// <summary> /// The thread main of the message reading and processing thread. /// </summary> private void MessageReader() { try { object messageEnvelope = null; while ((messageEnvelope = _messageObjectStream.Read()) != null) { MessageBase message = GetMessageFromEnvelope(messageEnvelope); if (message == null) { this.Error("Received unexpected message envelope of type '{0}' -> ignore it.", messageEnvelope.GetType().Name); continue; } if (message.GetType().Name == "KeepAliveRequest") { var response = new KeepAliveResponseEnvelope() { KeepAliveResponse = new KeepAliveResponse() { Id = message.Id, Source = message.Destination, Destination = message.Source } }; _messageObjectStream.Write(response); continue; } lock (_activeInterceptors) { foreach (var interceptor in _activeInterceptors) { if (interceptor.InterceptMessage(message)) { message = null; break; } } } if ((message != null) && (this.MessageArrived != null)) { this.Trace( "MessageArrived event is raised: a new message arrived that is not handled by any pending message interceptors."); this.MessageArrived(this, new MessageArrivedArgs() { Message = message }); } } } catch (Exception ex) { this.Error("Reading and dispatching messages failed!", ex); } finally { lock (_activeInterceptors) { foreach (var interceptor in _activeInterceptors) { interceptor.Cancel(); } } _threadDownEvent.Set(); } try { if (this.MessageStreamDown != null) { this.MessageStreamDown(this, null); } } catch (Exception ex) { this.Error("Throwing final message stream down event failed!", ex); } }
/// <summary> /// Reads the next Mosaic message from the underlying connection and returns it. This method will block until a new Mosaic message /// has been read, the converter stream has been cancelled or an error occurred. /// </summary> /// <returns> /// Read Mosaic message if successful; <c>null</c> otherwise. /// </returns> public MosaicMessage Read() { while (true) { IMessageConversion message = null; while (message == null) { object readMessage = _objectStream.Read(); if (readMessage == null) { return(null); } if (readMessage.GetType() == typeof(KeepAliveRequestEnvelope)) { var request = (KeepAliveRequestEnvelope)readMessage; var response = new KeepAliveResponseEnvelope() { KeepAliveResponse = new KeepAliveResponse() { Id = request.KeepAliveRequest.Id, Source = _configuration.SubscriberID, Destination = request.KeepAliveRequest.Source } }; if (_objectStream.Write(response) == false) { this.Error("Sending keep alive response with ID '{0}' failed.", request.KeepAliveRequest.Id); return(null); } continue; } if (readMessage.GetType() == typeof(KeepAliveResponseEnvelope)) { var response = (KeepAliveResponseEnvelope)readMessage; if (TypeConverter.ConvertInt(response.KeepAliveResponse.Id) == _keepAliveID) { System.Threading.Interlocked.Exchange(ref _lastKeepAlive, 0); continue; } this.Error("Received orphan keep alive response with ID '{0}' but expected ID '{1}'.", response.KeepAliveResponse.Id, _keepAliveID); return(null); } message = readMessage as IMessageConversion; if (message == null) { this.Error("Ignored unsupported message of type '{0}'.", readMessage.GetType().FullName); continue; } } var mosaicMessage = message.ToMosaicMessage(this); if (mosaicMessage != null) { mosaicMessage.TenantID = _tenantID; } return(mosaicMessage); } }