Ejemplo n.º 1
0
        /// <summary>
        /// This event handles incoming messages from communication channel.
        /// </summary>
        /// <param name="sender">Communication channel that received message</param>
        /// <param name="e">Event arguments</param>
        private void CommunicationChannel_MessageReceived(ICommunicationChannel sender, MessageReceivedEventArgs e)
        {
            LastIncomingMessageTime = DateTime.Now;

            if ((e.Message.MessageTypeId == NGRIDMessageFactory.MessageTypeIdNGRIDControllerMessage) && (!string.IsNullOrEmpty(e.Message.RepliedMessageId)))
            {
                //Find and send signal/pulse to waiting thread for this message
                WaitingMessage waitingMessage = null;
                lock (_waitingMessages)
                {
                    if (_waitingMessages.ContainsKey(e.Message.RepliedMessageId))
                    {
                        waitingMessage = _waitingMessages[e.Message.RepliedMessageId];
                    }
                }

                if (waitingMessage != null)
                {
                    waitingMessage.ResponseMessage = e.Message as NGRIDControllerMessage;
                    waitingMessage.WaitEvent.Set();
                    return;
                }
            }

            //Add message to queue to process in a seperated thread
            _incomingMessageQueue.Add(e.Message);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handles MessageReceived event of Messenger object.
        /// </summary>
        /// <param name="sender">Source of event</param>
        /// <param name="e">Event arguments</param>
        private void Messenger_MessageReceived(object sender, MessageEventArgs e)
        {
            //Check if there is a waiting thread for this message in SendMessageAndWaitForResponse method
            if (!string.IsNullOrEmpty(e.Message.RepliedMessageId))
            {
                WaitingMessage waitingMessage = null;
                lock (_syncObj)
                {
                    if (_waitingMessages.ContainsKey(e.Message.RepliedMessageId))
                    {
                        waitingMessage = _waitingMessages[e.Message.RepliedMessageId];
                    }
                }

                //If there is a thread waiting for this response message, pulse it
                if (waitingMessage != null)
                {
                    waitingMessage.ResponseMessage = e.Message;
                    waitingMessage.State           = WaitingMessageStates.ResponseReceived;
                    waitingMessage.WaitEvent.Set();
                    return;
                }
            }

            _incomingMessageProcessor.EnqueueMessage(e.Message);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Sends a mssage to MDS server and waits a response for timeoutMilliseconds milliseconds.
        /// </summary>
        /// <param name="message">Message to send</param>
        /// <param name="waitingResponseType">What type of response is being waited</param>
        /// <param name="timeoutMilliseconds">Maximum waiting time for response</param>
        /// <returns>Received message from server</returns>
        private MDSMessage SendAndWaitForReply(MDSMessage message, int waitingResponseType, int timeoutMilliseconds)
        {
            //Create a WaitingMessage to wait and get response message and add it to waiting messages
            var waitingMessage = new WaitingMessage(waitingResponseType);

            lock (_waitingMessages)
            {
                _waitingMessages[message.MessageId] = waitingMessage;
            }

            try
            {
                //Create a WaitingMessage to wait and get response message and add it to waiting messages
                SendMessageInternal(message);

                //Send message to the server
                waitingMessage.WaitEvent.WaitOne(timeoutMilliseconds);

                //Check for errors
                switch (waitingMessage.State)
                {
                case WaitingMessageStates.WaitingForResponse:
                    throw new MDSTimeoutException("Timeout occured. Can not received response to message.");

                case WaitingMessageStates.ClientDisconnected:
                    throw new MDSException("Client disconnected from MDS server before response received to message.");

                case WaitingMessageStates.MessageRejected:
                    throw new MDSException("Message is rejected by MDS server or destination application.");
                }

                if (waitingMessage.ResponseMessage == null)
                {
                    throw new MDSException("An unexpected error occured, message can not send.");
                }

                return(waitingMessage.ResponseMessage);
            }
            finally
            {
                //Remove message from waiting messages
                lock (_waitingMessages)
                {
                    if (_waitingMessages.ContainsKey(message.MessageId))
                    {
                        _waitingMessages.Remove(message.MessageId);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// This method is handles all adjacent server's and client application's MessageReceived events.
        /// </summary>
        /// <param name="sender">Creator of event</param>
        /// <param name="e">Event arguments</param>
        private void RemoteApplication_MessageReceived(object sender, MessageReceivedFromRemoteApplicationEventArgs e)
        {
            try
            {
                //Incoming data transfer message request
                if (e.Message.MessageTypeId == NGRIDMessageFactory.MessageTypeIdNGRIDDataTransferMessage)
                {
                    //Get, check and process message
                    var dataTransferMessage = e.Message as NGRIDDataTransferMessage;
                    ProcessDataTransferMessage(e.Application as NGRIDPersistentRemoteApplicationBase, e.Communicator, dataTransferMessage);
                }
                //Incoming delivery result (ACK/Reject message)
                else if ((e.Message.MessageTypeId == NGRIDMessageFactory.MessageTypeIdNGRIDOperationResultMessage) &&
                         (!string.IsNullOrEmpty(e.Message.RepliedMessageId)))
                {
                    //Find and send signal/pulse to waiting thread for this message
                    WaitingMessage waitingMessage = null;
                    lock (_waitingMessages)
                    {
                        if (_waitingMessages.ContainsKey(e.Message.RepliedMessageId))
                        {
                            waitingMessage = _waitingMessages[e.Message.RepliedMessageId];
                        }
                    }

                    if (waitingMessage != null)
                    {
                        waitingMessage.ResponseMessage = e.Message as NGRIDOperationResultMessage;
                        waitingMessage.WaitEvent.Set();
                    }
                }
                //Incoming Ping message
                else if ((e.Message.MessageTypeId == NGRIDMessageFactory.MessageTypeIdNGRIDPingMessage) &&
                         string.IsNullOrEmpty(e.Message.RepliedMessageId))
                {
                    //Reply ping message
                    e.Application.SendMessage(new NGRIDPingMessage {
                        RepliedMessageId = e.Message.MessageId
                    },
                                              e.Communicator);
                }
            }
            catch (Exception ex)
            {
                Logger.Warn(ex.Message, ex);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Sends a message and waits a response for that message.
        /// </summary>
        /// <remarks>
        /// Response message is matched with RepliedMessageId property, so if any other message (that
        /// is not reply for sent message) is received from remote application, it is not considered
        /// as a reply and is not returned as return value of this method.
        ///
        /// MessageReceived event is not raised for response messages.
        /// </remarks>
        /// <param name="message">message to send</param>
        /// <param name="timeoutMilliseconds">Timeout duration as milliseconds.</param>
        /// <returns>Response message</returns>
        /// <exception cref="TimeoutException">
        /// Throws TimeoutException if can not receive reply message in timeout value
        /// </exception>
        /// <exception cref="CommunicationException">
        /// Throws CommunicationException if communication fails before reply message.
        /// </exception>
        public IScsMessage SendMessageAndWaitForResponse(IScsMessage message, int timeoutMilliseconds, byte priority)
        {
            // Create a waiting message record and add to list
            WaitingMessage waitingMessage = new WaitingMessage();

            lock (_syncObj)
            {
                _waitingMessages[message.MessageId] = waitingMessage;
            }

            try
            {
                // Send message
                Messenger.SendMessage(message, priority);

                // Wait for response
                waitingMessage.WaitEvent.Wait(timeoutMilliseconds);

                // Check for exceptions
                switch (waitingMessage.State)
                {
                case WaitingMessageStates.WaitingForResponse:
                    Logger.Error(new TimeoutException("Timeout occured. Can not received response."));
                    break;

                case WaitingMessageStates.Cancelled:
                    Logger.Error(new CommunicationException("Disconnected before response received."));
                    break;
                }

                // return response message
                return(waitingMessage.ResponseMessage);
            }
            finally
            {
                // Remove message from waiting messages
                lock (_syncObj)
                {
                    if (_waitingMessages.ContainsKey(message.MessageId))
                    {
                        _waitingMessages.Remove(message.MessageId);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Sends a ControlMessage to NGRID server and gets it's response message.
        /// </summary>
        /// <param name="message">Message to send</param>
        /// <returns>Response message from server</returns>
        public ControlMessage SendMessageAndGetResponse(ControlMessage message)
        {
            //Create a WaitingMessage to wait and get response message and add it to waiting messages
            var outgoingMessage = new NGRIDControllerMessage
            {
                MessageData             = NGRIDSerializationHelper.SerializeToByteArray(message),
                ControllerMessageTypeId = message.MessageTypeId
            };
            var waitingMessage = new WaitingMessage();

            lock (_waitingMessages)
            {
                _waitingMessages[outgoingMessage.MessageId] = waitingMessage;
            }

            try
            {
                //Send message to the server
                SendMessageInternal(outgoingMessage);

                //Wait until thread is signalled by another thread to get response (Signalled by CommunicationChannel_MessageReceived method)
                waitingMessage.WaitEvent.WaitOne(TimeSpan.FromSeconds(90));

                //Check if response received or timeout occured
                if (waitingMessage.ResponseMessage == null)
                {
                    throw new NGRIDException("Timeout occured. Response message did not received.");
                }

                return(DeserializeControlMessage(waitingMessage.ResponseMessage));
            }
            finally
            {
                //Remove message from waiting messages
                lock (_waitingMessages)
                {
                    if (_waitingMessages.ContainsKey(outgoingMessage.MessageId))
                    {
                        _waitingMessages.Remove(outgoingMessage.MessageId);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Sends a message and waits a response for that message.
        /// </summary>
        /// <remarks>
        /// Response message is matched with RepliedMessageId property, so if
        /// any other message (that is not reply for sent message) is received
        /// from remote application, it is not considered as a reply and is not
        /// returned as return value of this method.
        ///
        /// MessageReceived event is not raised for response messages.
        /// </remarks>
        /// <param name="message">message to send</param>
        /// <param name="timeoutMilliseconds">Timeout duration as milliseconds.</param>
        /// <returns>Response message</returns>
        /// <exception cref="TimeoutException">Throws TimeoutException if can not receive reply message in timeout value</exception>
        /// <exception cref="CommunicationException">Throws CommunicationException if communication fails before reply message.</exception>
        public ICJiaMessage SendMessageAndWaitForResponse(ICJiaMessage message, int timeoutMilliseconds)
        {
            //Create a waiting message record and add to list
            var waitingMessage = new WaitingMessage();

            lock (_syncObj)
            {
                _waitingMessages[message.MessageId] = waitingMessage;
            }

            try
            {
                //Send message
                Messenger.SendMessage(message);

                //Wait for response
                waitingMessage.WaitEvent.Wait(timeoutMilliseconds);

                //Check for exceptions
                switch (waitingMessage.State)
                {
                case WaitingMessageStates.WaitingForResponse:
                    throw new TimeoutException("操作超时.远程服务器无响应.");

                case WaitingMessageStates.Cancelled:
                    throw new CommunicationException("收到响应前连接被中断.");
                }

                //return response message
                return(waitingMessage.ResponseMessage);
            }
            finally
            {
                //Remove message from waiting messages
                lock (_syncObj)
                {
                    if (_waitingMessages.ContainsKey(message.MessageId))
                    {
                        _waitingMessages.Remove(message.MessageId);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        public RaceGameplayScene()
            : base("race-gameplay")
        {
            StatusDisplay = new RaceDataDisplay();

            _countdownPopup = new CountdownPopup();
            _quitRaceButton = new QuitRaceButton();
            _powerUpButton  = new PowerUpButton();
            _playerEventPopup.AnimationCompletionHandler = HandlePlayerEventAnimationComplete;

            _powerUpDisplayTimer = new PowerUpTimer();
            _powerUpDisplayTimer.TickCallback = _timerController.RegisterUpdateCallback;
            _powerUpHelper         = new PowerUpHelper();
            _blackout              = new Blackout();
            _blackout.TickCallback = _timerController.RegisterUpdateCallback;

            _positionStatusPopup = new RaceInfoPopup();
            _raceEventPopup      = new RaceInfoPopup();
            _waitingMessage      = new WaitingMessage();

            _exitTimer = new Timer("", HandleExitTimerActionComplete);
            GlobalTimerController.GlobalTimer.RegisterUpdateCallback(_exitTimer.Tick);

            _startSequenceTimer = new Timer("", HandleStartCountdownStep);
            GlobalTimerController.GlobalTimer.RegisterUpdateCallback(_startSequenceTimer.Tick);

            _quitTimer = new Timer("", HandleQuitTimerActionComplete);
            GlobalTimerController.GlobalTimer.RegisterUpdateCallback(_quitTimer.Tick);

            _quitRaceDialog = new QuitRaceDialog();
            _quitRaceDialog.CancellationTimer = _quitTimer;
            _quitRaceDialog.InputSources.Add(_inputProcessor);

            _disconnectedDialog = new DisconnectedDialog();
            _disconnectedDialog.SelectionCallback = HandleDisconnectAcknowledge;
            _disconnectedDialog.InputSources.Add(_inputProcessor);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Sends message directly to application (not stores) and waits ACK.
        /// This method adds message to queue by NGRIDPersistentRemoteApplicationBase.AddMessageToHeadOfQueue method
        /// and waits a signal/pulse from RemoteApplication_MessageReceived method to get ACK/Reject.
        /// </summary>
        /// <param name="senderApplication">Sender application/server</param>
        /// <param name="senderCommunicator">Sender communicator</param>
        /// <param name="destApplication">Destination application/server</param>
        /// <param name="message">Message</param>
        private void SendMessageDirectly(NGRIDRemoteApplication senderApplication, ICommunicator senderCommunicator, NGRIDPersistentRemoteApplicationBase destApplication, NGRIDDataTransferMessage message)
        {
            //Create a WaitingMessage to wait and get ACK/Reject message and add it to waiting messages
            var waitingMessage = new WaitingMessage();

            lock (_waitingMessages)
            {
                _waitingMessages[message.MessageId] = waitingMessage;
            }

            try
            {
                //Add message to head of queue of remote application
                destApplication.AddMessageToHeadOfQueue(message);

                //Wait until thread is signalled by another thread to get response (Signalled by RemoteApplication_MessageReceived method)
                waitingMessage.WaitEvent.WaitOne((int)(_settings.MessageResponseTimeout * 1.2));

                //Evaluate response
                if (waitingMessage.ResponseMessage.Success)
                {
                    SendOperationResultMessage(senderApplication, senderCommunicator, message, true, "Success.");
                }
                else
                {
                    SendOperationResultMessage(senderApplication, senderCommunicator, message, false, "Message is not acknowledged. Reason: " + waitingMessage.ResponseMessage.ResultText);
                }
            }
            finally
            {
                //Remove message from waiting messages
                lock (_waitingMessages)
                {
                    _waitingMessages.Remove(message.MessageId);
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Sends a ControlMessage to MDS server and gets it's response message.
        /// </summary>
        /// <param name="message">Message to send</param>
        /// <returns>Response message from server</returns>
        public ControlMessage SendMessageAndGetResponse(ControlMessage message)
        {
            //Create a WaitingMessage to wait and get response message and add it to waiting messages
            var outgoingMessage = new MDSControllerMessage
                                      {
                                          MessageData = MDSSerializationHelper.SerializeToByteArray(message),
                                          ControllerMessageTypeId = message.MessageTypeId
                                      };
            var waitingMessage = new WaitingMessage();
            lock (_waitingMessages)
            {
                _waitingMessages[outgoingMessage.MessageId] = waitingMessage;
            }

            try
            {
                //Send message to the server
                SendMessageInternal(outgoingMessage);

                //Wait until thread is signalled by another thread to get response (Signalled by CommunicationChannel_MessageReceived method)
                waitingMessage.WaitEvent.WaitOne(TimeSpan.FromSeconds(90));

                //Check if response received or timeout occured
                if(waitingMessage.ResponseMessage == null)
                {
                    throw new MDSException("Timeout occured. Response message did not received.");
                }
                
                return DeserializeControlMessage(waitingMessage.ResponseMessage);
            }
            finally
            {
                //Remove message from waiting messages
                lock (_waitingMessages)
                {
                    if (_waitingMessages.ContainsKey(outgoingMessage.MessageId))
                    {
                        _waitingMessages.Remove(outgoingMessage.MessageId);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// This method evaluates ACK/Reject messages from remote application for a data transfer message.
        /// </summary>
        /// <param name="communicator">Communicator that sent message</param>
        /// <param name="operationResultMessage">Response message</param>
        /// <param name="waitingMessage">Waiting message for this response (may be null, if it is null, it is searched in _waitingMessages list)</param>
        private void EvaluateResponse(ICommunicator communicator, MDSOperationResultMessage operationResultMessage, WaitingMessage waitingMessage)
        {
            lock (_waitingMessages)
            {
                //If waitingMessage argument is not supplied, find waiting message from _waitingMessages list
                if (waitingMessage == null)
                {
                    foreach (var wMessage in _waitingMessages)
                    {
                        if (wMessage.State == WaitingMessage.WaitingMessageStates.WaitingForAcknowledgment &&
                            wMessage.MessageRecord.MessageId == operationResultMessage.RepliedMessageId)
                        {
                            waitingMessage = wMessage;
                            break;
                        }
                    }

                    //If there is not message that waits for this response, just exit from method..
                    if (waitingMessage == null)
                    {
                        return;
                    }
                }

                //If message is stored to database in this server
                if (waitingMessage.MessageRecord.Id >= 0)
                {
                    if (operationResultMessage.Success)
                    {
                        //If message is persistent (Stored on database), remove from database.
                        if (waitingMessage.MessageRecord.Id > 0)
                        {
                            StorageManager.RemoveMessage(waitingMessage.MessageRecord.Id);
                        }

                        //Remove from list
                        _waitingMessages.Remove(waitingMessage);
                        //Reset _waitingTimeOnError (because this is a success situation)
                        _waitingTimeOnError = FirstWaitingTimeOnError;
                    }
                    else
                    {
                        //Set message state as 'ready to send' again. Thus, message is added to send queue again.
                        waitingMessage.State = WaitingMessage.WaitingMessageStates.ReadyToSend;
                        //Pulse if a thread waiting in ProcessWaitingMessageRecords method
                        Monitor.PulseAll(_waitingMessages);
                    }
                }
                //If message is not stored to database in this server
                else
                {
                    //Remove from list
                    _waitingMessages.Remove(waitingMessage);
                }

                Logger.Debug("EvaluateResponse - WaitingMessages.Count = " + _waitingMessages.Count + ", Application = " + Name);
            }

            //If it is not stored message..
            if (waitingMessage.MessageRecord.Id < 0)
            {
                //Create event to send response message to upper layers
                OnMessageReceived(this, new MessageReceivedFromCommunicatorEventArgs
                {
                    Communicator = communicator,
                    Message      = operationResultMessage
                });
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Process one MDSMessageRecord from queue.
 /// Called by ProcessWaitingMessageRecords method for each message.
 /// If waitingMessage.MessageRecord.Id > 0 that means the message is asyncronous (added to queue with EnqueueMessage and stored to database),
 /// else the message is syncronous (added to queue with AddMessageToHeadOfQueue method).
 /// Asyncronous messages will be tried again and again until it is delivered,
 /// but syncronsous messages is tried only one time to send, because sender application waits response for it.
 /// </summary>
 /// <param name="waitingMessage">Message to process</param>
 private void ProcessWaitingMessage(WaitingMessage waitingMessage)
 {
     try
     {
         waitingMessage.State = WaitingMessage.WaitingMessageStates.WaitingForAcknowledgment;
         //If message is stored to database (waitingMessage.MessageRecord.Id > 0)...
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             //Set DestinationCommunicatorId = 0, because this field can not be used on persistent messages.
             waitingMessage.MessageRecord.Message.DestinationCommunicatorId = 0;
             //No timeout value, so, wait a free communicator for infinity
             SendDataMessage(waitingMessage.MessageRecord.Message, 0);
         }
         else
         {
             SendDataMessage(waitingMessage.MessageRecord.Message, Settings.MessageResponseTimeout);
         }
     }
     catch (MDSNoCommunicatorException ex)
     {
         Logger.Warn(ex.Message, ex);
         EvaluateResponse(null, new MDSOperationResultMessage
         {
             RepliedMessageId = waitingMessage.MessageRecord.MessageId,
             ResultText       = ex.Message,
             Success          = false
         }, waitingMessage);
         //If it was stored message, stop processing messages until a receiver communicator is connected
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             WaitUntilReceiverCommunicatorConnected();
         }
     }
     catch (MDSTimeoutException ex)
     {
         Logger.Warn(ex.Message, ex);
         EvaluateResponse(null, new MDSOperationResultMessage
         {
             RepliedMessageId = waitingMessage.MessageRecord.MessageId,
             ResultText       = ex.Message,
             Success          = false
         }, waitingMessage);
         //If it was stored message, wait a while before processing messages
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             WaitOnError();
         }
     }
     catch (Exception ex)
     {
         Logger.Error(ex.Message, ex);
         EvaluateResponse(null, new MDSOperationResultMessage
         {
             RepliedMessageId = waitingMessage.MessageRecord.MessageId,
             ResultText       = ex.Message,
             Success          = false
         }, waitingMessage);
         //If it was stored message, wait a while before processing messages
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             WaitOnError();
         }
     }
 }
Ejemplo n.º 13
0
        private void __ProcessMiddlewareMessageRecived(MiddlewareTransferPackage mtMsg)
        {
            if (mtMsg is RequestMTPackage)
            {
                //向上请求消息
                _middlewareCorelogicLayer.MiddlewareTransferMessageRecived(mtMsg as RequestMTPackage);
            }
            if (mtMsg is ReplyMTPackage)
            {
                //Noting to do, push up
                ReplyMTPackage mtReplyPkg         = mtMsg as ReplyMTPackage;
                bool           bAsynArrIndexExist = false;
                bool           bSynArrIndexExist  = false;
                lock (_synReadLockObject)
                {
                    if (false == string.IsNullOrEmpty(mtReplyPkg.RepliedMessageId))
                    {
                        bAsynArrIndexExist = _asynWattingMiddlewareReplyMessages.ContainsKey(mtReplyPkg.RepliedMessageId);
                        bSynArrIndexExist  = _synWattingMiddlewareReplyMessages.ContainsKey(mtReplyPkg.RepliedMessageId);
                    }
                }
                if ((false == bAsynArrIndexExist) &&
                    (false == bSynArrIndexExist))
                {
                    //一个未知的应答消息,没有索引,丢弃
                }
                else
                {
                    if (true == bSynArrIndexExist)
                    {
                        //处理同步消息
                        WaitingMessage waitingMessage = null;
                        lock (_synReadLockObject)
                        {
                            if (_synWattingMiddlewareReplyMessages.ContainsKey(mtReplyPkg.RepliedMessageId))
                            {
                                waitingMessage = _synWattingMiddlewareReplyMessages[mtReplyPkg.RepliedMessageId] as WaitingMessage;
                            }
                        }

                        //If there is a thread waiting for this response message, pulse it
                        if (waitingMessage != null)
                        {
                            waitingMessage.ResponseMessage = mtReplyPkg;
                            waitingMessage.State           = MiddlewareTransferServerStateInfo.ResponseReceived;
                            waitingMessage.WaitEvent.Set();
                            return;
                        }
                    }
                    else
                    {
                        //处理异步消息
                        MiddlewareTransferPackage sourMtPkg = _asynWattingMiddlewareReplyMessages[mtReplyPkg.RepliedMessageId] as MiddlewareTransferPackage;
                        _middlewareCorelogicLayer.MiddlewareTransferMessageRecived(sourMtPkg, mtReplyPkg);

                        //清理资源
                        bool havWattingRecored;
                        lock (_synReadLockObject)
                        {
                            havWattingRecored = _asynWattingMiddlewareReplyMessages.ContainsKey(mtReplyPkg.RepliedMessageId);
                        }
                        if (havWattingRecored)
                        {
                            _asynWattingMiddlewareReplyMessages.Remove(mtReplyPkg.RepliedMessageId);
                        }
                    }
                }
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Sends a mssage to NGRID server and waits a response for timeoutMilliseconds milliseconds.
        /// </summary>
        /// <param name="message">Message to send</param>
        /// <param name="waitingResponseType">What type of response is being waited</param>
        /// <param name="timeoutMilliseconds">Maximum waiting time for response</param>
        /// <returns>Received message from server</returns>
        private NGRIDMessage SendAndWaitForReply(NGRIDMessage message, int waitingResponseType, int timeoutMilliseconds)
        {
            //Create a WaitingMessage to wait and get response message and add it to waiting messages
            var waitingMessage = new WaitingMessage(waitingResponseType);
            lock (_waitingMessages)
            {
                _waitingMessages[message.MessageId] = waitingMessage;
            }

            try
            {
                //Create a WaitingMessage to wait and get response message and add it to waiting messages
                SendMessageInternal(message);

                //Send message to the server
                waitingMessage.WaitEvent.WaitOne(timeoutMilliseconds);

                //Check for errors
                switch (waitingMessage.State)
                {
                    case WaitingMessageStates.WaitingForResponse:
                        throw new NGRIDTimeoutException("Timeout occured. Can not received response to message.");
                    case WaitingMessageStates.ClientDisconnected:
                        throw new NGRIDException("Client disconnected from NGRID server before response received to message.");
                    case WaitingMessageStates.MessageRejected:
                        throw new NGRIDException("Message is rejected by NGRID server or destination application.");
                }

                if (waitingMessage.ResponseMessage == null)
                {
                    throw new NGRIDException("An unexpected error occured, message can not send.");
                }

                return waitingMessage.ResponseMessage;
            }
            finally
            {
                //Remove message from waiting messages
                lock (_waitingMessages)
                {
                    if (_waitingMessages.ContainsKey(message.MessageId))
                    {
                        _waitingMessages.Remove(message.MessageId);
                    }
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// This event handles incoming messages from communication channel.
        /// </summary>
        /// <param name="sender">Communication channel that received message</param>
        /// <param name="e">Event arguments</param>
        private void CommunicationChannel_MessageReceived(ICommunicationChannel sender, Communication.Channels.MessageReceivedEventArgs e)
        {
            //Update last incoming message time
            LastIncomingMessageTime = DateTime.Now;

            //Check for duplicate messages.
            if (e.Message.MessageTypeId == MDSMessageFactory.MessageTypeIdMDSDataTransferMessage)
            {
                var dataMessage = e.Message as MDSDataTransferMessage;
                if (dataMessage != null)
                {
                    if (dataMessage.MessageId == LastAcknowledgedMessageId)
                    {
                        try
                        {
                            SendMessageInternal(new MDSOperationResultMessage
                            {
                                RepliedMessageId = dataMessage.MessageId,
                                Success          = true,
                                ResultText       = "Duplicate message."
                            });
                        }
                        catch (Exception ex)
                        {
                            Logger.Warn(ex.Message, ex);
                        }

                        return;
                    }
                }
            }

            //Check if there is a waiting thread for this message (in SendAndWaitForReply method)
            if (!string.IsNullOrEmpty(e.Message.RepliedMessageId))
            {
                WaitingMessage waitingMessage = null;
                lock (_waitingMessages)
                {
                    if (_waitingMessages.ContainsKey(e.Message.RepliedMessageId))
                    {
                        waitingMessage = _waitingMessages[e.Message.RepliedMessageId];
                    }
                }

                if (waitingMessage != null)
                {
                    if (waitingMessage.WaitingResponseType == e.Message.MessageTypeId)
                    {
                        waitingMessage.ResponseMessage = e.Message;
                        waitingMessage.State           = WaitingMessageStates.ResponseReceived;
                        waitingMessage.WaitEvent.Set();
                        return;
                    }

                    if (e.Message.MessageTypeId == MDSMessageFactory.MessageTypeIdMDSOperationResultMessage)
                    {
                        var resultMessage = e.Message as MDSOperationResultMessage;
                        if ((resultMessage != null) && (!resultMessage.Success))
                        {
                            waitingMessage.State = WaitingMessageStates.MessageRejected;
                            waitingMessage.WaitEvent.Set();
                            return;
                        }
                    }
                }
            }

            //If this message is not a response, then add it to message process queue
            _incomingMessageQueue.Add(e.Message);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Sends message directly to application (not stores) and waits ACK.
        /// This method adds message to queue by MDSPersistentRemoteApplicationBase.AddMessageToHeadOfQueue method
        /// and waits a signal/pulse from RemoteApplication_MessageReceived method to get ACK/Reject.
        /// </summary>
        /// <param name="senderApplication">Sender application/server</param>
        /// <param name="senderCommunicator">Sender communicator</param>
        /// <param name="destApplication">Destination application/server</param>
        /// <param name="message">Message</param>
        private void SendMessageDirectly(MDSRemoteApplication senderApplication, ICommunicator senderCommunicator, MDSPersistentRemoteApplicationBase destApplication, MDSDataTransferMessage message)
        {
            //Create a WaitingMessage to wait and get ACK/Reject message and add it to waiting messages
            var waitingMessage = new WaitingMessage();
            lock (_waitingMessages)
            {
                _waitingMessages[message.MessageId] = waitingMessage;
            }

            try
            {
                //Add message to head of queue of remote application
                destApplication.AddMessageToHeadOfQueue(message);

                //Wait until thread is signalled by another thread to get response (Signalled by RemoteApplication_MessageReceived method)
                waitingMessage.WaitEvent.WaitOne((int) (_settings.MessageResponseTimeout*1.2));

                //Evaluate response
                if (waitingMessage.ResponseMessage.Success)
                {
                    SendOperationResultMessage(senderApplication, senderCommunicator, message, true, "Success.");
                }
                else
                {
                    SendOperationResultMessage(senderApplication, senderCommunicator, message, false, "Message is not acknowledged. Reason: " + waitingMessage.ResponseMessage.ResultText);
                }
            }
            finally
            {
                //Remove message from waiting messages
                lock (_waitingMessages)
                {
                    _waitingMessages.Remove(message.MessageId);
                }
            }
        }
 /// <summary>
 /// Process one NGRIDMessageRecord from queue.
 /// Called by ProcessWaitingMessageRecords method for each message.
 /// If waitingMessage.MessageRecord.Id > 0 that means the message is asyncronous (added to queue with EnqueueMessage and stored to database),
 /// else the message is syncronous (added to queue with AddMessageToHeadOfQueue method).
 /// Asyncronous messages will be tried again and again until it is delivered, 
 /// but syncronsous messages is tried only one time to send, because sender application waits response for it.
 /// </summary>
 /// <param name="waitingMessage">Message to process</param>
 private void ProcessWaitingMessage(WaitingMessage waitingMessage)
 {
     try
     {
         waitingMessage.State = WaitingMessage.WaitingMessageStates.WaitingForAcknowledgment;
         //If message is stored to database (waitingMessage.MessageRecord.Id > 0)...
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             //Set DestinationCommunicatorId = 0, because this field can not be used on persistent messages.
             waitingMessage.MessageRecord.Message.DestinationCommunicatorId = 0;
             //No timeout value, so, wait a free communicator for infinity
             SendDataMessage(waitingMessage.MessageRecord.Message, 0);
         }
         else
         {
             SendDataMessage(waitingMessage.MessageRecord.Message, Settings.MessageResponseTimeout);
         }
     }
     catch (NGRIDNoCommunicatorException ex)
     {
         Logger.Warn(ex.Message, ex);
         EvaluateResponse(null, new NGRIDOperationResultMessage
                                    {
                                        RepliedMessageId = waitingMessage.MessageRecord.MessageId,
                                        ResultText = ex.Message,
                                        Success = false
                                    }, waitingMessage);
         //If it was stored message, stop processing messages until a receiver communicator is connected
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             WaitUntilReceiverCommunicatorConnected();
         }
     }
     catch (NGRIDTimeoutException ex)
     {
         Logger.Warn(ex.Message, ex);
         EvaluateResponse(null, new NGRIDOperationResultMessage
                                    {
                                        RepliedMessageId = waitingMessage.MessageRecord.MessageId,
                                        ResultText = ex.Message,
                                        Success = false
                                    }, waitingMessage);
         //If it was stored message, wait a while before processing messages
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             WaitOnError();
         }
     }
     catch (Exception ex)
     {
         Logger.Error(ex.Message, ex);
         EvaluateResponse(null, new NGRIDOperationResultMessage
                                    {
                                        RepliedMessageId = waitingMessage.MessageRecord.MessageId,
                                        ResultText = ex.Message,
                                        Success = false
                                    }, waitingMessage);
         //If it was stored message, wait a while before processing messages
         if (waitingMessage.MessageRecord.Id >= 0)
         {
             WaitOnError();
         }
     }
 }
Ejemplo n.º 18
0
        private MiddlewareTransferPackage __SendMessageAndWattingForResponse(MiddlewareTransferPackage msg, int timeoutMilliseconds)
        {
            WaitingMessage waitMsg = new WaitingMessage();

            lock (_synWriteLockObject)
            {
                _synWattingMiddlewareReplyMessages[msg.MessageId] = waitMsg;
            }

            //send message
            bool mustWaitReponse = true;
            ServerRequestPackage wilSendServMsg = new ServerRequestPackage(mustWaitReponse);

            //配置为中间件传输包
            IMiddleware2MiddlewareCommunicatRequest statSetter = wilSendServMsg.Active_MiddlewareCommunicatRequest();

            statSetter.WilSendMiddleware2MiddlewareMessage(msg.TargetDevice, msg);

            BinTransferLayer   btlpeocessor = _middlewareCorelogicLayer.BinTransferProcessor;
            ServerReplyPackage replyServPkg = null;

            try
            {
                replyServPkg = btlpeocessor.SynSendMessage(wilSendServMsg, 100000);
            }
            catch (System.Exception ex)
            {
                //释放锁记录
                lock (_synWriteLockObject)
                {
                    _synWattingMiddlewareReplyMessages.Remove(msg.MessageId);
                }
                throw new MiddlewareTransferErrorExcetion(ex.ToString());
            }
            //分析服务端报文
            IMiddleware2MiddlewareCommunicatReply replyInterface = replyServPkg.Active_Middleware2MiddlewareCommunicatReply();
            bool   ret;
            string detail;

            replyInterface.SendMiddlewareMsgOprRet(out ret, out detail);
            if (true == ret)
            {
                //noting to do
            }
            else
            {
                throw new MiddlewareTransferErrorExcetion(detail);
            }

            //wait for the recived event
            waitMsg.WaitEvent.Wait(timeoutMilliseconds);

            //Check for exceptions
            switch (waitMsg.State)
            {
            case MiddlewareTransferServerStateInfo.WaittingForResponse:
            {
                //同步超时
                lock (_synWriteLockObject)
                {
                    _synWattingMiddlewareReplyMessages.Remove(msg.MessageId);
                }
                throw new MiddlewareTransferErrorExcetion(MiddlewareTransferServerStateInfo.TimeOut.ToString());
            }

            case MiddlewareTransferServerStateInfo.ResponseReceived:
            {
                lock (_synWriteLockObject)
                {
                    _synWattingMiddlewareReplyMessages.Remove(msg.MessageId);
                }
                break;
            }
            }
            return(waitMsg.ResponseMessage);
        }
        /// <summary>
        /// This method evaluates ACK/Reject messages from remote application for a data transfer message.
        /// </summary>
        /// <param name="communicator">Communicator that sent message</param>
        /// <param name="operationResultMessage">Response message</param>
        /// <param name="waitingMessage">Waiting message for this response (may be null, if it is null, it is searched in _waitingMessages list)</param>
        private void EvaluateResponse(ICommunicator communicator, NGRIDOperationResultMessage operationResultMessage, WaitingMessage waitingMessage)
        {
            lock (_waitingMessages)
            {
                //If waitingMessage argument is not supplied, find waiting message from _waitingMessages list
                if (waitingMessage == null)
                {
                    foreach (var wMessage in _waitingMessages)
                    {
                        if (wMessage.State == WaitingMessage.WaitingMessageStates.WaitingForAcknowledgment &&
                            wMessage.MessageRecord.MessageId == operationResultMessage.RepliedMessageId)
                        {
                            waitingMessage = wMessage;
                            break;
                        }
                    }

                    //If there is not message that waits for this response, just exit from method..
                    if (waitingMessage == null)
                    {
                        return;
                    }
                }

                //If message is stored to database in this server
                if (waitingMessage.MessageRecord.Id >= 0)
                {
                    if (operationResultMessage.Success)
                    {
                        //If message is persistent (Stored on database), remove from database.
                        if (waitingMessage.MessageRecord.Id > 0)
                        {
                            StorageManager.RemoveMessage(waitingMessage.MessageRecord.Id);
                        }

                        //Remove from list
                        _waitingMessages.Remove(waitingMessage);
                        //Reset _waitingTimeOnError (because this is a success situation)
                        _waitingTimeOnError = FirstWaitingTimeOnError;
                    }
                    else
                    {
                        //Set message state as 'ready to send' again. Thus, message is added to send queue again.
                        waitingMessage.State = WaitingMessage.WaitingMessageStates.ReadyToSend;
                        //Pulse if a thread waiting in ProcessWaitingMessageRecords method
                        Monitor.PulseAll(_waitingMessages);
                    }
                }
                //If message is not stored to database in this server
                else
                {
                    //Remove from list
                    _waitingMessages.Remove(waitingMessage);
                }

                Logger.Debug("EvaluateResponse - WaitingMessages.Count = " + _waitingMessages.Count + ", Application = " + Name);
            }

            //If it is not stored message..
            if (waitingMessage.MessageRecord.Id < 0)
            {
                //Create event to send response message to upper layers
                OnMessageReceived(this, new MessageReceivedFromCommunicatorEventArgs
                                        {
                                            Communicator = communicator,
                                            Message = operationResultMessage
                                        });
            }
        }