/// <summary> /// Sends a message to another component /// </summary> /// <param name="address">The destination address of the message</param> /// <param name="message">The message to send</param> public void SendMessage(Message message) { // Enqueue the message for processing by Dispatch threads messages.Enqueue(message); }
/// <summary> /// Attempts to route the specified message /// </summary> /// <remarks>The server should check if the target of this message is a remote component and /// if not, attempt to discover it. Any exception thrown by this message will be used to /// return an error message to the sender</remarks> /// <param name="m">The message to route</param> public void RouteMessage(Message m) { RemoteComponent rc = remoteComponents[m.Target]; string scheme = rc.Address.Substring(0, rc.Address.IndexOf(':')); if (!protocols.ContainsKey(scheme)) { string msg = "Invalid Scheme (" + scheme + "), could not find matching protocol handler"; log.Error("[RouteMessage] " + msg); throw new InvalidOperationException(msg); } IProtocol protocol = protocols[scheme]; protocol.Send(m, rc.Address); log.Info("[RouteMessage] Message for component \"" + m.Target + "\" routed to: " + rc.Address); }
/// <summary> /// Dispatches the specified control message /// </summary> /// <param name="m">A control message to dispatch</param> public object DispatchControl(Message m) { object r = null; switch (m.Action.ToUpper()) { case "ADDRECIEVER": AddReciever(); log.Info("[Dispatch] AddReciever"); return null; case "REMOVERECIEVER": RemoveReciever(); log.Info("[Dispatch] RemoveReciever"); return null; case "ADDDISPATCHER": AddDispatcher(); log.Info("[Dispatch] AddDispatcher"); return null; case "REMOVEDISPATCHER": RemoveDispatcher(); log.Info("[Dispatch] RemoveDispatcher"); return null; case "GETRTHREADCOUNT": r = (object)GetRThreadCount(); log.Info("[Dispatch] GetRThreadCount"); return r; case "GETDTHREADCOUNT": r = (object)GetDThreadCount(); log.Info("[Dispatch] GetDThreadCount"); return r; case "REGISTERCOMPONENT": RegisterComponent((RemoteComponent)m.Arguments[0]); log.Info("[Dispatch] RegisterComponent"); return null; case "UNREGISTERCOMPONENT": UnregisterComponent((string)m.Arguments[0]); log.Info("[Dispatch] UnregisterComponent"); return null; case "RESOLVECONTRACT": r = (object)ResolveContract((string)m.Arguments[0]); log.Info("[Dispatch] ResolveContract"); return r; case "GETNAME": log.Info("[Dispatch] GetName"); return name; case "SENDMESSAGE": SendMessage((Message)m.Arguments[0]); log.Info("[Dispatch] SendMessage"); return null; } return null; }
private void RecieveLoop() { // Start at 0 int i = 0; if (protocols.Count == 0) return; Monitor.Enter(locker); while (!stop) { // Setup variables Message m = null; IProtocol p = null; // Lock the protocol list and get a protocol Monitor.Enter(protocols); p = protocols[i]; Monitor.Exit(protocols); // Recieve a Message m = p.Recieve(); if (m != null) { // TODO: Use log4net Nested Diagnostic Context to log messages that occur during the processing of a message // If the target is local, enqueue the message if (server.Manager.Contains(m.Target)) server.Messages.Enqueue(m); // If the target is remote, or we can discover it, route the message else if ((server.RemoteComponents.ContainsKey(m.Target)) || (server.Discover(m.Target))) server.SendMessage(m); // Otherwise, if we don't know the component, we can't recieve the message else { // Log the error string message = "Unable to locate target component (" + m.Target + ") for this message"; log.Error(message); // If we do know how to reach the sender (i.e. its local or known remote) if ((server.Manager.Contains(m.Sender)) || (server.RemoteComponents.ContainsKey(m.Sender))) { // Create an exception message and send it with the same RefId but with our server name as the sender Message err = new Message("ERR", m.Sender, "SRV:" + server.Name); err.Arguments.Add(new NullReferenceException(message)); err.Type = MessageTypeEnum.Exception; err.RefId = m.RefId; server.SendMessage(err); } // Don't log that we recieved the message continue; } log.Info("Message Recieved by " + p.Scheme + " protocol"); } // If we are on the last protocol, go back to 0 if (i == (protocols.Count - 1)) i = 0; // Otherwise, move on to the next protocol else i++; // Let others modify the stop flag Monitor.Wait(locker); } }
/// <summary> /// Adds the specified message to the queue /// </summary> /// <param name="msg">The message to add to the queue</param> public void Enqueue(Message msg) { // Add message to appropriate sub-queue switch (msg.Priority) { case MessagePriorityEnum.Low: lock(locker) lowQueue.Enqueue(msg); return; case MessagePriorityEnum.Normal: lock(locker) midQueue.Enqueue(msg); return; case MessagePriorityEnum.High: lock(locker) highQueue.Enqueue(msg); return; } }
/// <summary> /// Sends a message to another component /// </summary> /// <param name="address">The destination address of the message</param> /// <param name="message">The message to send</param> public void SendMessage(Message message) { if (manager.Contains(message.Target)) { messages.Enqueue(message); } else if (remoteComponents.ContainsKey(message.Target)) { RemoteComponent rc = remoteComponents[message.Target]; string scheme = rc.Address.Substring(0, rc.Address.IndexOf(':')); if (!protocols.ContainsKey(scheme)) { string msg = "Invalid Scheme (" + scheme + "), could not find matching protocol handler"; log.Error("[SendMessage] " + msg); throw new InvalidDataException(msg); } IProtocol protocol = protocols[scheme]; protocol.Send(message, rc.Address); log.Info("[SendMessage] Message for component \"" + message.Target + "\" routed to: " + rc.Address); } else { log.Error("[SendMessage] Unable to send message to component: " + message.Target + ", component is not registered or attached"); } }