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;
            }
        }
예제 #2
0
        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());
                }
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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;
                    }
                }
            }
        }