function broker_task() { // Prepare our context and sockets $context = new ZMQContext(); $frontend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $backend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $frontend->bind("tcp://*:5555"); $backend->bind("tcp://*:5556"); // Initialize poll set $poll = new ZMQPoll(); $poll->add($frontend, ZMQ::POLL_IN); $poll->add($backend, ZMQ::POLL_IN); $read = $write = array(); while (true) { $events = $poll->poll($read, $write); foreach ($read as $socket) { $zmsg = new Zmsg($socket); $zmsg->recv(); if ($socket === $frontend) { $zmsg->push("W"); $zmsg->set_socket($backend)->send(); } elseif ($socket === $backend) { $zmsg->pop(); $zmsg->push("C"); $zmsg->set_socket($frontend)->send(); } } } }
private function sendCommand($command, $msg = null) { if (!$msg) { $msg = new Zmsg(); } $msg->push($command); $msg->push(Commands::W_WORKER); $msg->push(""); if ($this->verbose) { printf("I: sending `%s` to broker %s", $command, PHP_EOL); echo $msg->__toString(), PHP_EOL; } $msg->set_socket($this->socket)->send(); }
/** * Send request to broker * Takes ownership of request message and destroys it when sent. * * @param string $service * @param Zmsg $request */ public function send($service, Zmsg $request) { // Prefix request with protocol frames // Frame 0: empty (REQ emulation) // Frame 1: "MDPCxy" (six bytes, MDP/Client x.y) // Frame 2: Service name (printable string) $request->push($service); $request->push(MDPC_CLIENT); $request->push(""); if ($this->verbose) { printf("I: send request to '%s' service: %s", $service, PHP_EOL); echo $request->__toString(); } $request->set_socket($this->client)->send(); }
public function send($data) { $msg = new Zmsg($this->socket); $msg->push($data); $msg->wrap(sprintf("%.0f", microtime(1) * 1000)); $msg->send(true); }
/** * Process message sent to us by a worker * * @param string $sender * @param Zmsg $msg */ public function worker_process($sender, $msg) { $command = $msg->pop(); $worker_ready = isset($this->workers[$sender]); $worker = $this->worker_require($sender); if ($command == MDPW_READY) { if ($worker_ready) { $this->worker_delete($worker, true); // Not first command in session } else { if (strlen($sender) >= 4 && substr($sender, 0, 4) == 'mmi.') { $this->worker_delete($worker, true); } else { // Attach worker to service and mark as idle $service_frame = $msg->pop(); $worker->service = $this->service_require($service_frame); $worker->service->workers++; $this->worker_waiting($worker); } } } else { if ($command == MDPW_REPLY) { if ($worker_ready) { // Remove & save client return envelope and insert the // protocol header and service name, then rewrap envelope. $client = $msg->unwrap(); $msg->push($worker->service->name); $msg->push(MDPC_CLIENT); $msg->wrap($client, ""); $msg->set_socket($this->socket)->send(); $this->worker_waiting($worker); } else { $this->worker_delete($worker, true); } } else { if ($command == MDPW_HEARTBEAT) { if ($worker_ready) { $worker->expiry = microtime(true) + HEARTBEAT_EXPIRY / 1000; } else { $this->worker_delete($worker, true); } } else { if ($command == MDPW_DISCONNECT) { $this->worker_delete($worker, true); } else { echo "E: invalid input message", PHP_EOL, $msg->__toString(); } } } } }
/** * Send request to broker and get reply by hook or crook * Takes ownership of request message and destroys it when sent. * Returns the reply message or NULL if there was no reply. * * @param string $service * @param Zmsg $request * @param string $client * @return Zmsg */ public function send($service, Zmsg $request) { // Prefix request with protocol frames // Frame 1: "MDPCxy" (six bytes, MDP/Client // Frame 2: Service name (printable string) $request->push($service); $request->push(MDPC_CLIENT); if ($this->verbose) { printf("I: send request to '%s' service:", $service); echo $request->__toString(); } $retries_left = $this->retries; $read = $write = array(); while ($retries_left) { $request->set_socket($this->client)->send(); // Poll socket for a reply, with timeout $poll = new ZMQPoll(); $poll->add($this->client, ZMQ::POLL_IN); $events = $poll->poll($read, $write, $this->timeout); // If we got a reply, process it if ($events) { $request->recv(); if ($this->verbose) { echo "I: received reply:", $request->__toString(), PHP_EOL; } // Don't try to handle errors, just assert noisily assert($request->parts() >= 3); $header = $request->pop(); assert($header == MDPC_CLIENT); $reply_service = $request->pop(); assert($reply_service == $service); return $request; // Success } elseif ($retries_left--) { if ($this->verbose) { echo "W: no reply, reconnecting...", PHP_EOL; } // Reconnect, and resend message $this->connect_to_broker(); $request->send(); } else { echo "W: permanent error, abandoning request", PHP_EOL; break; // Give up } } }
$session = new Mdcli("tcp://localhost:5555", $verbose); // 1. Send 'echo' request to Titanic $request = new Zmsg(); $request->push("Hello world"); $request->push("echo"); $reply = s_service_call($session, "titanic.request", $request); $uuid = null; if ($reply) { $uuid = $reply->pop(); printf("I: request UUID %s %s", $uuid, PHP_EOL); } // 2. Wait until we get a reply while (true) { usleep(100000); $request = new Zmsg(); $request->push($uuid); $reply = s_service_call($session, "titanic.reply", $request); if ($reply) { $reply_string = $reply->last(); printf("Reply: %s %s", $reply_string, PHP_EOL); // 3. Close request $request = new Zmsg(); $request->push($uuid); $reply = s_service_call($session, "titanic.close", $request); break; } else { echo "I: no reply yet, trying again...", PHP_EOL; usleep(5000000); // Try again in 5 seconds } }
/** * Attempt to process a single request, return 1 if successful * * @param Mdcli $client * @param string $uuid */ function s_service_success($client, $uuid) { // Load request message, service will be first frame $filename = s_request_filename($uuid); $fh = fopen($filename, "r"); // If the client already closed request, treat as successful if (!$fh) { return true; } $request = new Zmsg(); $request->load($fh); fclose($fh); $service = $request->pop(); // Use MMI protocol to check if service is available $mmi_request = new Zmsg(); $mmi_request->push($service); $mmi_reply = $client->send("mmi.service", $mmi_request); $service_ok = $mmi_reply && $mmi_reply->pop() == "200"; if ($service_ok) { $reply = $client->send($service, $request); $filename = s_reply_filename($uuid); $fh = fopen($filename, "w"); assert($fh); $reply->save($fh); fclose($fh); return true; } return false; }