Example #1
0
 public static MessageData DecodeMessage(ZMessage message) =>
 new MessageData
 {
     Identity = message.Pop().ReadInt32(),
     Type     = (MessageType)message.Pop().ReadAsByte(),
     Data     = message.Select((frame) => frame.Read()).ToArray()
 };
Example #2
0
        public void Pop()
        {
            const string test1 = "__TEST1__", test2 = "__TEST2__";
            var          msg = new ZMessage {
                new ZFrame(test1), new ZFrame(test2)
            };
            var frame = msg.Pop();

            Assert.AreEqual(0, frame.Position);
            Assert.AreEqual(new ZFrame(test1), frame);
        }
Example #3
0
        //  .split try to call a service
        //  Here, we first check if the requested MDP service is defined or not,
        //  using a MMI lookup to the Majordomo broker. If the service exists,
        //  we send a request and wait for a reply using the conventional MDP
        //  client API. This is not meant to be fast, just very simple:

        static bool Titanic_ServiceSuccess(Guid uuid, CancellationTokenSource cts)
        {
            // Load request message, service will be first frame
            string     fn = TitanicCommon.RequestFilename(uuid);
            FileStream fs;

            if (!fn.TryFileOpenRead(out fs))
            {
                // If the client already close request, treat as successful
                return(true);
            }
            fs.Dispose();

            ZMessage request     = fn.DeserializeFromXml <ZMessage>();
            var      service     = request.Pop();
            string   servicename = service.ToString();
            bool     res         = false;

            // Create MDP client session with short timeout
            using (var client = new MajordomoClient("tcp://127.0.0.1:5555", false))
            {
                client.Set_Timeout(1000);                 // 1sec
                client.Set_Retries(1);                    // only 1 retry

                // Use MMI protocol to check if service is available
                ZMessage mmirequest = new ZMessage {
                    service
                };

                bool service_ok;
                using (var mmireply = client.Send("mmi.service", mmirequest, cts))
                    service_ok = (mmireply != null &&
                                  mmireply.First().ToString().Equals("200"));

                res = false;
                if (service_ok)
                {
                    using (ZMessage reply = client.Send(servicename, request, cts))
                        if (reply != null)
                        {
                            fn = TitanicCommon.ReplyFilename(uuid);
                            reply.SerializeToXml(fn);
                            res = true;
                        }
                        else
                        {
                            request.Dispose();
                        }
                }
            }
            return(res);
        }
Example #4
0
            public void RouterMessage(ZMessage reply)
            {
                // This method processes one message from a connected
                // server:

                // Frame 0 is server that replied
                string endpoint;

                using (var endpointFrame = reply.Pop())
                {
                    endpoint = endpointFrame.ReadString();
                }

                Server server = this.Servers.Single(s => s.Endpoint == endpoint);

                if (!server.Alive)
                {
                    this.Actives.Add(server);
                    server.Refresh(true);
                }

                // Frame 1 may be sequence number for reply
                int sequence;

                using (var sequenceFrame = reply.Pop())
                {
                    sequence = sequenceFrame.ReadInt32();
                }
                if (sequence == this.sequence)
                {
                    reply.Prepend(new ZFrame("OK"));

                    this.Pipe.Send(reply);

                    this.Request.Dispose();
                    this.Request = null;
                }
            }
Example #5
0
            //  .split broker client_msg method
            //  Process a request coming from a client. We implement MMI requests
            //  directly here (at present, we implement only the mmi.service request):
            public void ClientMsg(ZFrame sender, ZMessage msg)
            {
                // service & body
                if (msg.Count < 2)
                {
                    throw new InvalidOperationException();
                }

                using (ZFrame serviceFrame = msg.Pop())
                {
                    Service service = RequireService(serviceFrame);

                    // Set reply return identity to client sender
                    msg.Wrap(sender.Duplicate());

                    //if we got a MMI Service request, process that internally
                    if (serviceFrame.Length >= 4 &&
                        serviceFrame.ToString().StartsWith("mmi."))
                    {
                        string returnCode;
                        if (serviceFrame.ToString().Equals("mmi.service"))
                        {
                            string name = msg.Last().ToString();
                            returnCode = Services.ContainsKey(name) &&
                                         Services[name].Workers > 0
                                            ? "200"
                                            : "404";
                        }
                        else
                        {
                            returnCode = "501";
                        }

                        var client = msg.Unwrap();

                        msg.Clear();
                        msg.Add(new ZFrame(returnCode));
                        msg.Prepend(serviceFrame);
                        msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));

                        msg.Wrap(client);
                        Socket.Send(msg);
                    }
                    else
                    {
                        // Else dispatch the message to the requested Service
                        service.Dispatch(msg);
                    }
                }
            }
Example #6
0
            public void ControlMessage(ZMessage msg)
            {
                // This method processes one message from our frontend class
                // (it's going to be CONNECT or REQUEST):

                string command;

                using (var commandFrame = msg.Pop())
                {
                    command = commandFrame.ReadString();
                }

                if (command == "CONNECT")
                {
                    string endpoint = msg[0].ReadString();
                    Console.WriteLine("I: connecting to {0}...", endpoint);

                    Router.Connect(endpoint);

                    var server = new Server(endpoint);
                    this.Servers.Add(server);
                    this.Actives.Add(server);
                }
                else if (command == "REQUEST")
                {
                    if (this.Request != null)
                    {
                        // Strict request-reply cycle
                        throw new InvalidOperationException();
                    }

                    // Prefix request with sequence number and empty envelope
                    msg.Prepend(new ZFrame(++sequence));

                    // Take ownership of request message
                    this.Request = msg.Duplicate();

                    // Request expires after global timeout
                    this.Expires = DateTime.UtcNow + GLOBAL_TIMEOUT;
                }
            }
Example #7
0
        //  .split Titanic close task
        //  The {{titanic.close}} task removes any waiting replies for the request
        //  (specified by UUID). It's idempotent, so it is safe to call more than
        //  once in a row:
        private static void Titanic_Close(ZContext context, CancellationTokenSource cts, bool verbose)
        {
            using (var worker = new MajordomoWorker("tcp://127.0.0.1:5555", "titanic.close", verbose))
            {
                ZMessage reply = null;
                while (true)
                {
                    ZMessage request = worker.Recv(reply, cts);
                    if (request == null)
                    {
                        break;
                    }

                    var g     = Guid.Parse(request.Pop().ReadString());
                    var reqfn = TitanicCommon.RequestFilename(g);
                    var repfn = TitanicCommon.ReplyFilename(g);
                    File.Delete(reqfn);
                    File.Delete(repfn);
                    request.Dispose();
                    reply = new ZMessage();
                    reply.Add(new ZFrame("200"));
                }
            }
        }
Example #8
0
            //  .split broker client_msg method
            //  Process a request coming from a client. We implement MMI requests
            //  directly here (at present, we implement only the mmi.service request):
            public void ClientMsg(ZFrame sender, ZMessage msg)
            {
                // service & body
                if(msg.Count < 2)
                    throw new InvalidOperationException();

                using (ZFrame serviceFrame = msg.Pop())
                {
                    Service service = RequireService(serviceFrame);

                    // Set reply return identity to client sender
                    msg.Wrap(sender.Duplicate());

                    //if we got a MMI Service request, process that internally
                    if (serviceFrame.Length >= 4
                        && serviceFrame.ToString().StartsWith("mmi."))
                    {
                        string returnCode;
                        if (serviceFrame.ToString().Equals("mmi.service"))
                        {
                            string name = msg.Last().ToString();
                            returnCode = Services.ContainsKey(name)
                                         && Services[name].Workers > 0
                                            ? "200"
                                            : "404";
                        }
                        else
                            returnCode = "501";

                        var client = msg.Unwrap();

                        msg.Clear();
                        msg.Add(new ZFrame(returnCode));
                        msg.Prepend(serviceFrame);
                        msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));

                        msg.Wrap(client);
                        Socket.Send(msg);
                    }
                    else
                    {
                        // Else dispatch the message to the requested Service
                        service.Dispatch(msg);
                    }
                }
            }
Example #9
0
            //  .split broker worker_msg method
            //  This method processes one READY, REPLY, HEARTBEAT, or
            //  DISCONNECT message sent to the broker by a worker:
            public void WorkerMsg(ZFrame sender, ZMessage msg)
            {
                if(msg.Count < 1) // At least, command
                    throw new InvalidOperationException();

                ZFrame command = msg.Pop();
                //string id_string = sender.ReadString();
                bool isWorkerReady;
                //string id_string;
                using (var sfrm = sender.Duplicate())
                {
                    var idString = sfrm.Read().ToHexString();
                    isWorkerReady = Workers.ContainsKey(idString);
                }
                Worker worker = RequireWorker(sender);
                using (msg)
                using (command)
                {
                    if (command.StrHexEq(MdpCommon.MdpwCmd.READY))
                    {
                        if (isWorkerReady)
                            // Not first command in session
                            worker.Delete(true);
                        else if (command.Length >= 4
                              && command.ToString().StartsWith("mmi."))
                            // Reserd servicee name
                            worker.Delete(true);
                        else
                        {
                            // Attach worker to service and mark as idle
                            using (ZFrame serviceFrame = msg.Pop())
                            {
                                worker.Service = RequireService(serviceFrame);
                                worker.Service.Workers++;
                                worker.Waiting();
                            }
                        }
                    }
                    else if (command.StrHexEq(MdpCommon.MdpwCmd.REPLY))
                    {
                        if (isWorkerReady)
                        {
                            //  Remove and save client return envelope and insert the
                            //  protocol header and service name, then rewrap envelope.
                            ZFrame client = msg.Unwrap();
                            msg.Prepend(new ZFrame(worker.Service.Name));
                            msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                            msg.Wrap(client);
                            Socket.Send(msg);
                            worker.Waiting();
                        }
                        else
                        {
                            worker.Delete(true);
                        }
                    }
                    else if (command.StrHexEq(MdpCommon.MdpwCmd.HEARTBEAT))
                    {
                        if (isWorkerReady)
                        {
                            worker.Expiry = DateTime.UtcNow + MdpCommon.HEARTBEAT_EXPIRY;
                        }
                        else
                        {
                            worker.Delete(true);
                        }
                    }
                    else if (command.StrHexEq(MdpCommon.MdpwCmd.DISCONNECT))
                        worker.Delete(false);
                    else
                    {
                        msg.DumpZmsg("E: invalid input message");
                    }
                }
            }
Example #10
0
            //  .split broker client_msg method
            //  Process a request coming from a client. We implement MMI requests
            //  directly here (at present, we implement only the mmi.service request):
            public void ClientMsg(ZFrame sender, ZMessage msg)
            {
                // service & body
                if(msg.Count < 2)
                    throw new InvalidOperationException();

                using (ZFrame serviceFrame = msg.Pop())
                {
                    Service service = RequireService(serviceFrame);

                    // Set reply return identity to client sender
                    msg.Wrap(sender.Duplicate());

                    //if we got a MMI Service request, process that internally
                    if (serviceFrame.Length >= 4
                        && serviceFrame.ToString().StartsWith("mmi."))
                    {
                        string returnCode;
                        if (serviceFrame.ToString().Equals("mmi.service"))
                        {
                            string name = msg.Last().ToString();
                            returnCode = Services.ContainsKey(name)
                                         && Services[name].Workers > 0
                                            ? "200"
                                            : "400";
                        }
                        else
                            returnCode = "501";

                        using (var resetableFrame = msg.Pop())
                        {
                            msg.Prepend(new ZFrame(returnCode));
                        }

                        //ToDo check c implementation
                        throw new NotImplementedException("ToDo: fix this section, never tested. contains errors mmi services never called with the mdclient/mdbroker/mdworker examples");
                        //## following code has some errors

                        //  Remove & save client return envelope and insert the
                        //  protocol header and Service name, then rewrap envelope.
                        ZFrame client = msg.Unwrap();
                        msg.Prepend(serviceFrame);
                        msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                        msg.Wrap(client);
                        Socket.Send(msg);
                    }
                    else
                    {
                        // Else dispatch the message to the requested Service
                        service.Dispatch(msg);
                    }
                }
            }
Example #11
0
            //  .split broker worker_msg method
            //  This method processes one READY, REPLY, HEARTBEAT, or
            //  DISCONNECT message sent to the broker by a worker:
            public void WorkerMsg(ZFrame sender, ZMessage msg)
            {
                if (msg.Count < 1) // At least, command
                {
                    throw new InvalidOperationException();
                }

                ZFrame command = msg.Pop();
                //string id_string = sender.ReadString();
                bool isWorkerReady;

                //string id_string;
                using (var sfrm = sender.Duplicate())
                {
                    var idString = sfrm.Read().ToHexString();
                    isWorkerReady = Workers.ContainsKey(idString);
                }
                Worker worker = RequireWorker(sender);

                using (msg)
                    using (command)
                    {
                        if (command.StrHexEq(MdpCommon.MdpwCmd.READY))
                        {
                            if (isWorkerReady)
                            {
                                // Not first command in session
                                worker.Delete(true);
                            }
                            else if (command.Length >= 4 &&
                                     command.ToString().StartsWith("mmi."))
                            {
                                // Reserd servicee name
                                worker.Delete(true);
                            }
                            else
                            {
                                // Attach worker to service and mark as idle
                                using (ZFrame serviceFrame = msg.Pop())
                                {
                                    worker.Service = RequireService(serviceFrame);
                                    worker.Service.Workers++;
                                    worker.Waiting();
                                }
                            }
                        }
                        else if (command.StrHexEq(MdpCommon.MdpwCmd.REPLY))
                        {
                            if (isWorkerReady)
                            {
                                //  Remove and save client return envelope and insert the
                                //  protocol header and service name, then rewrap envelope.
                                ZFrame client = msg.Unwrap();
                                msg.Prepend(new ZFrame(worker.Service.Name));
                                msg.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT));
                                msg.Wrap(client);
                                Socket.Send(msg);
                                worker.Waiting();
                            }
                            else
                            {
                                worker.Delete(true);
                            }
                        }
                        else if (command.StrHexEq(MdpCommon.MdpwCmd.HEARTBEAT))
                        {
                            if (isWorkerReady)
                            {
                                worker.Expiry = DateTime.UtcNow + MdpCommon.HEARTBEAT_EXPIRY;
                            }
                            else
                            {
                                worker.Delete(true);
                            }
                        }
                        else if (command.StrHexEq(MdpCommon.MdpwCmd.DISCONNECT))
                        {
                            worker.Delete(false);
                        }
                        else
                        {
                            msg.DumpZmsg("E: invalid input message");
                        }
                    }
            }