/// <summary> /// Dispatchs a single message /// </summary> /// <param name="xmlData">The body of the message</param> /// <param name="replyToId">The identifier of the object to respond to /// Might be null if the message is already a response</param> /// <param name="srcId">Source unit id</param> public void DispatchMessage(string xmlData, string replyToId, string srcId) { try { MessageAccess msg = new MessageAccess(xmlData); String msgName = msg.GetMessageName(); Type handlerType = (Type)_msgHandlers[msgName]; if (handlerType != null) { object o = Activator.CreateInstance(handlerType); IMessageHandler handler = (IMessageHandler)o; HandlerData p = new HandlerData(handler, msg, replyToId, srcId); ThreadPool.QueueUserWorkItem(new WaitCallback(FireMessageHandler), p); } } catch (Exception ex) { Debug.WriteLine("BecsMsgDispatcher.DispatchMessage error - " + ex.Message); BecsMain.Logger.AddLog(ex); } }
/// <summary> /// Just processes the message, delegating the real work on the corresponding class /// To do so, just creates the message class and calls it's Process method /// </summary> /// <param name="msgAccess">An accessor to the received message</param> /// <param name="replyToId">The identifier of the object to reply to</param> /// <param name="srcId">Source Unit Id</param> public void ProcessUserMessage(MessageAccess msgAccess, string replyToId, string srcId) { // Delegate message processing to the subclass that // really handles the process, and sends back the // response to MSMQ. TODO: Save response in MSGS string body = msgAccess.ToString(); BecsMain.Logger.AddLog("[BecsMessageHandler]:Received message(body): " + body, LoggerSeverities.Debug); BecsMain.Logger.AddLog("[BecsMessageHandler]:# Starting message processing ", LoggerSeverities.Debug); IRecvMessage msg = null; try { // Gets an instance of the class that processes the message msg = MessageFactory.GetReceivedMessage(body); msg.Session = BecsEngine.Session.MessagesSession; } catch (Exception) { // This exception means that message has not been created // This is probably because parameters are incorrect StringCollection nack = new StringCollection(); nack.Add(new NackMessage(MessageFactory.GetIdFromMessage(body), NackMessage.NackTypes.NACK_SEMANTIC).ToString()); SendResponsesBack(nack, replyToId, srcId); LogMsgDB(srcId, msgAccess.GetMessageName(), body, nack, replyToId); return; } try { BecsMain.Logger.AddLog("[BecsMessageHandler]:# Process Message", LoggerSeverities.Debug); BecsMain.Logger.AddLog("[BecsMessageHandler]ProcessUserMessage " + msg.MsgId.ToString(), LoggerSeverities.Debug); BecsMain.Logger.AddLog("[BecsMessageHandler]From UnitId: " + srcId, LoggerSeverities.Debug); // Execute the real processing of the message System.Collections.Specialized.StringCollection sc = msg.Process(); // Send back all responses SendResponsesBack(sc, replyToId, srcId); LogMsgDB(srcId, msgAccess.GetMessageName(), body, sc, replyToId); } catch (System.Threading.ThreadAbortException) { // Thread was cancelled by user (stopping service, etc) // Must send a nack to the client with code "FE" BecsMain.Logger.AddLog("[BecsMessageHandler]:Thread " + System.Threading.Thread.CurrentThread.GetHashCode() + " aborted.", LoggerSeverities.Info); StringCollection nack = new StringCollection(); nack.Add(new NackMessage(msg.MsgId, NackMessage.NackTypes.NACK_ERROR_BECS, 0xFE).ToString()); SendResponsesBack(nack, replyToId, srcId); LogMsgDB(srcId, msgAccess.GetMessageName(), body, nack, replyToId); } catch (System.Exception ex) { // An unknown exception has happened // Must send a nack with code "FF" BecsMain.Logger.AddLog(ex); StringCollection nack = new StringCollection(); nack.Add(new NackMessage(msg.MsgId, NackMessage.NackTypes.NACK_ERROR_BECS, 0xFF).ToString()); SendResponsesBack(nack, replyToId, srcId); LogMsgDB(srcId, msgAccess.GetMessageName(), body, nack, replyToId); } }