} $reroutable = false; $events = $poll->poll($readable, $writeable, 0); if ($events > 0) { foreach ($readable as $socket) { $zmsg = new Zmsg($socket); $zmsg->recv(); if ($local_capacity) { $zmsg->wrap(array_shift($worker_queue), ""); $zmsg->set_socket($localbe)->send(); $local_capacity--; } else { // Route to random broker peer printf("I: route request %s to cloud...%s", $zmsg->body(), PHP_EOL); $zmsg->wrap($_SERVER['argv'][mt_rand(2, $_SERVER['argc'] - 1)]); $zmsg->set_socket($cloudbe)->send(); } } } else { break; // No work, go back to backends } } if ($local_capacity != $previous) { // Broadcast new capacity $zmsg = new Zmsg($statebe); $zmsg->body_set($local_capacity); // We stick our own address onto the envelope $zmsg->wrap($self)->send(); } }
<?php /* * MMI echo query example * * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ include 'mdcliapi.php'; $verbose = $_SERVER['argc'] > 1 && $_SERVER['argv'][1] == '-v'; $session = new MDCli("tcp://localhost:5555", $verbose); // This is the service we want to look up $request = new Zmsg(); $request->body_set("echo"); // This is the service we send our request to $reply = $session->send("mmi.service", $request); if ($reply) { $reply_code = $reply->pop(); printf("Lookup echo service: %s %s", $reply_code, PHP_EOL); }
/** * Run a self test of the Zmsg class. * * @return boolean * @todo See if assert returns */ public static function test() { $result = true; $context = new ZMQContext(); $output = new ZMQSocket($context, ZMQ::SOCKET_XREQ); $output->bind("inproc://zmsg_selftest"); $input = new ZMQSocket($context, ZMQ::SOCKET_XREP); $input->connect("inproc://zmsg_selftest"); // Test send and receive of single-part message $zmsgo = new Zmsg($output); $zmsgo->body_set("Hello"); $result &= assert($zmsgo->body() == "Hello"); $zmsgo->send(); $zmsgi = new Zmsg($input); $zmsgi->recv(); $result &= assert($zmsgi->parts() == 2); $result &= assert($zmsgi->body() == "Hello"); echo $zmsgi; // Test send and receive of multi-part message $zmsgo = new Zmsg($output); $zmsgo->body_set("Hello"); $zmsgo->wrap("address1", ""); $zmsgo->wrap("address2"); $result &= assert($zmsgo->parts() == 4); echo $zmsgo; $zmsgo->send(); $zmsgi = new Zmsg($input); $zmsgi->recv(); $result &= assert($zmsgi->parts() == 5); $zmsgi->unwrap(); $result &= assert($zmsgi->unwrap() == "address2"); $zmsgi->body_fmt("%s%s", 'W', "orld"); $result &= assert($zmsgi->body() == "World"); // Pull off address 1, check that empty part was dropped $zmsgi->unwrap(); $result &= assert($zmsgi->parts() == 1); // Check that message body was correctly modified $part = $zmsgi->pop(); $result &= assert($part == "World"); $result &= assert($zmsgi->parts() == 0); // Test load and save $zmsg = new Zmsg(); $zmsg->body_set("Hello"); $zmsg->wrap("address1", ""); $zmsg->wrap("address2"); $result &= assert($zmsg->parts() == 4); $fh = fopen(sys_get_temp_dir() . "/zmsgtest.zmsg", 'w'); $zmsg->save($fh); fclose($fh); $fh = fopen(sys_get_temp_dir() . "/zmsgtest.zmsg", 'r'); $zmsg2 = new Zmsg(); $zmsg2->load($fh); assert($zmsg2->last() == $zmsg->last()); fclose($fh); $result &= assert($zmsg2->parts() == 4); echo $result ? "OK" : "FAIL", PHP_EOL; return $result; }
protected function workerSend(WorkerAddress $worker, $command, $data = null) { $zmsg = null; if ($data) { $zmsg = new Zmsg(); $zmsg->body_set($data); } $this->send($worker->address, $command, $zmsg); }
<?php /* * Majordomo Protocol client example - asynchronous * Uses the mdcli API to hide all MDP aspects * * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ include_once "mdcliapi2.php"; $verbose = $_SERVER['argc'] > 1 && $_SERVER['argv'][1] == '-v'; $session = new MDCli("tcp://localhost:5555", $verbose); for ($count = 0; $count < 10000; $count++) { $request = new Zmsg(); $request->body_set("Hello world"); $session->send("echo", $request); } for ($count = 0; $count < 10000; $count++) { $reply = $session->recv(); if (!$reply) { break; // Interrupt or failure } } printf("%d replies received", $count); echo PHP_EOL;
function main() { for ($client_nbr = 0; $client_nbr < NBR_CLIENTS; $client_nbr++) { $pid = pcntl_fork(); if ($pid == 0) { client_thread(); return; } } for ($worker_nbr = 0; $worker_nbr < NBR_WORKERS; $worker_nbr++) { $pid = pcntl_fork(); if ($pid == 0) { worker_thread(); return; } } $context = new ZMQContext(); $frontend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $backend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $frontend->bind("ipc://frontend.ipc"); $backend->bind("ipc://backend.ipc"); // Logic of LRU loop // - Poll backend always, frontend only if 1+ worker ready // - If worker replies, queue worker as ready and forward reply // to client if necessary // - If client requests, pop next worker and send request to it // Queue of available workers $available_workers = 0; $worker_queue = array(); $writeable = $readable = array(); while ($client_nbr > 0) { $poll = new ZMQPoll(); // Poll front-end only if we have available workers if ($available_workers > 0) { $poll->add($frontend, ZMQ::POLL_IN); } // Always poll for worker activity on backend $poll->add($backend, ZMQ::POLL_IN); $events = $poll->poll($readable, $writeable); if ($events > 0) { foreach ($readable as $socket) { // Handle worker activity on backend if ($socket === $backend) { // Queue worker address for LRU routing $zmsg = new Zmsg($socket); $zmsg->recv(); assert($available_workers < NBR_WORKERS); $available_workers++; array_push($worker_queue, $zmsg->unwrap()); if ($zmsg->body() != "READY") { $zmsg->set_socket($frontend)->send(); // exit after all messages relayed $client_nbr--; } } else { if ($socket === $frontend) { $zmsg = new Zmsg($socket); $zmsg->recv(); $zmsg->wrap(array_shift($worker_queue), ""); $zmsg->set_socket($backend)->send(); $available_workers--; } } } } } // Clean up our worker processes foreach ($worker_queue as $worker) { $zmsg = new Zmsg($backend); $zmsg->body_set('END')->wrap($worker, "")->send(); } sleep(1); }
$queue->s_worker_append($identity); } else { if ($zmsg->address() == 'HEARTBEAT') { $queue->s_worker_refresh($identity); } else { printf("E: invalid message from %s%s%s", $identity, PHP_EOL, $zmsg->__toString()); } } } else { $zmsg->set_socket($frontend)->send(); $queue->s_worker_append($identity); } } else { // Now get next client request, route to next worker $identity = $queue->s_worker_dequeue(); $zmsg->wrap($identity); $zmsg->set_socket($backend)->send(); } } if (microtime(true) > $heartbeat_at) { foreach ($queue as $id => $expiry) { $zmsg = new Zmsg($backend); $zmsg->body_set("HEARTBEAT"); $zmsg->wrap($identity, NULL); $zmsg->send(); } $heartbeat_at = microtime(true) + HEARTBEAT_INTERVAL; } $queue->s_queue_purge(); } }
private function send($data) { $zmsg = new Zmsg(); $zmsg->body_set($data); //@todo: wrap address; $this->sendCommand(Commands::W_RESPONSE, $zmsg); }