public MonitoredDuplexOutputChannel(IDuplexOutputChannel underlyingOutputChannel, ISerializer serializer, int pingFrequency, int receiveTimeout, IThreadDispatcher dispatcher) { using (EneterTrace.Entering()) { myUnderlyingOutputChannel = underlyingOutputChannel; mySerializer = serializer; myPingFrequency = pingFrequency; myReceiveTimeout = receiveTimeout; Dispatcher = dispatcher; MonitorChannelMessage aPingMessage = new MonitorChannelMessage(MonitorChannelMessageType.Ping, null); myPreserializedPingMessage = mySerializer.Serialize <MonitorChannelMessage>(aPingMessage); myPingingTimer = new EneterTimer(OnPingingTimerTick); myReceiveTimer = new EneterTimer(OnResponseTimerTick); myUnderlyingOutputChannel.ResponseMessageReceived += OnResponseMessageReceived; myUnderlyingOutputChannel.ConnectionOpened += OnConnectionOpened; myUnderlyingOutputChannel.ConnectionClosed += OnConnectionClosed; } }
private void OnMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { try { using (ThreadLock.Lock(myResponseReceiverContexts)) { TResponseReceiverContext aResponseReceiver = GetResponseReceiver(e.ResponseReceiverId); if (aResponseReceiver == null) { // Note: the response receiver was just disconnected. return; } aResponseReceiver.LastReceiveTime = DateTime.Now; } // Deserialize the incoming message. MonitorChannelMessage aMessage = mySerializer.Deserialize <MonitorChannelMessage>(e.Message); // if the message is ping, then response. if (aMessage.MessageType == MonitorChannelMessageType.Message) { // Notify the incoming message. DuplexChannelMessageEventArgs aMsg = new DuplexChannelMessageEventArgs(e.ChannelId, aMessage.MessageContent, e.ResponseReceiverId, e.SenderAddress); Dispatcher.Invoke(() => NotifyGeneric(MessageReceived, aMsg, true)); } } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToReceiveMessage, err); } } }
private void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { try { // Deserialize the message. MonitorChannelMessage aMessage = mySerializer.Deserialize <MonitorChannelMessage>(e.Message); // Note: timer setting is after deserialization. // reason: if deserialization fails the timer is not updated and the client will be disconnected. using (ThreadLock.Lock(myConnectionManipulatorLock)) { // Cancel the current response timeout and set the new one. myReceiveTimer.Change(myReceiveTimeout); } // If it is a message. if (aMessage.MessageType == MonitorChannelMessageType.Message) { Dispatcher.Invoke(() => Notify <DuplexChannelMessageEventArgs>(ResponseMessageReceived, new DuplexChannelMessageEventArgs(e.ChannelId, aMessage.MessageContent, e.ResponseReceiverId, e.SenderAddress), true)); } } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToReceiveMessage, err); } } }
public object Serialize <T>(T dataToSerialize) { using (EneterTrace.Entering()) { if (typeof(T) != typeof(MonitorChannelMessage)) { throw new InvalidOperationException("Only " + typeof(MonitorChannelMessage).Name + " can be serialized."); } object aTemp = dataToSerialize; MonitorChannelMessage aMessage = (MonitorChannelMessage)aTemp; using (MemoryStream aStream = new MemoryStream()) { BinaryWriter aWriter = new BinaryWriter(aStream); // Write message type. byte aMessageType = (byte)aMessage.MessageType; aWriter.Write((byte)aMessageType); // Write message data. if (aMessage.MessageType == MonitorChannelMessageType.Message) { if (aMessage.MessageContent == null) { throw new InvalidOperationException("Message data is null."); } myEncoderDecoder.Write(aWriter, aMessage.MessageContent, myIsLittleEndian); } return(aStream.ToArray()); } } }
public MonitoredDuplexInputChannel(IDuplexInputChannel underlyingInputChannel, ISerializer serializer, int pingFrequency, int receiveTimeout, IThreadDispatcher dispatcher) { using (EneterTrace.Entering()) { myUnderlyingInputChannel = underlyingInputChannel; mySerializer = serializer; myPingFrequency = pingFrequency; myReceiveTimeout = receiveTimeout; Dispatcher = dispatcher; myCheckTimer = new EneterTimer(OnCheckerTick); MonitorChannelMessage aPingMessage = new MonitorChannelMessage(MonitorChannelMessageType.Ping, null); myPreserializedPingMessage = mySerializer.Serialize <MonitorChannelMessage>(aPingMessage); } }
public void SendResponseMessage(string responseReceiverId, object message) { using (EneterTrace.Entering()) { try { // Create the response message for the monitor duplex output chanel. MonitorChannelMessage aMessage = new MonitorChannelMessage(MonitorChannelMessageType.Message, message); object aSerializedMessage = mySerializer.Serialize <MonitorChannelMessage>(aMessage); // Send the response message via the underlying channel. myUnderlyingInputChannel.SendResponseMessage(responseReceiverId, aSerializedMessage); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err); throw; } } }
public T Deserialize <T>(object serializedData) { using (EneterTrace.Entering()) { if (serializedData is byte[] == false) { throw new ArgumentException("Input parameter 'serializedData' is not byte[]."); } if (typeof(T) != typeof(MonitorChannelMessage)) { throw new InvalidOperationException("Data can be deserialized only into" + typeof(MonitorChannelMessage).Name); } MonitorChannelMessage aResult; byte[] aData = (byte[])serializedData; using (MemoryStream aStream = new MemoryStream(aData)) { BinaryReader aReader = new BinaryReader(aStream); // Read type of the message. int aRequest = aReader.ReadByte(); MonitorChannelMessageType aMessageType = (MonitorChannelMessageType)aRequest; // If it is the message then read data. object aMessageData = null; if (aMessageType == MonitorChannelMessageType.Message) { aMessageData = myEncoderDecoder.Read(aReader, myIsLittleEndian); } aResult = new MonitorChannelMessage(aMessageType, aMessageData); return((T)(object)aResult); } } }
public void SendMessage(object message) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { if (!IsConnected) { string anError = TracedObject + ErrorHandler.FailedToSendMessageBecauseNotConnected; EneterTrace.Error(anError); throw new InvalidOperationException(anError); } try { // Get the message recognized by the monitor duplex input channel. MonitorChannelMessage aMessage = new MonitorChannelMessage(MonitorChannelMessageType.Message, message); object aSerializedMessage = mySerializer.Serialize <MonitorChannelMessage>(aMessage); // Send the message by using the underlying messaging system. myUnderlyingOutputChannel.SendMessage(aSerializedMessage); // Reschedule the ping. myPingingTimer.Change(myPingFrequency); } catch (Exception err) { string anErrorMessage = TracedObject + ErrorHandler.FailedToSendMessage; EneterTrace.Error(anErrorMessage, err); CleanAfterConnection(true, true); throw; } } } }