public function mainAction() { echo "Madserver\n"; $context = new ZMQContext(); $sub_socket = new ZMQSocket($context, ZMQ::SOCKET_SUB); $sub_socket->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, ""); $sub_socket->setSockOpt(ZMQ::SOCKOPT_TCP_KEEPALIVE, 0); $sub_socket->setSockOpt(ZMQ::SOCKOPT_TCP_KEEPALIVE_IDLE, 10); $sub_socket->setSockOpt(ZMQ::SOCKOPT_TCP_KEEPALIVE_CNT, 2); $sub_socket->setSockOpt(ZMQ::SOCKOPT_TCP_KEEPALIVE_INTVL, 5); $sub_socket->connect("tcp://127.0.0.1:5557"); $snapshot = new ZMQSocket($context, ZMQ::SOCKET_DEALER); $snapshot->connect("tcp://127.0.0.1:5556"); $sequence = 1; $snapshot->sendmulti(array("ICANHAZ?", self::SUBTREE), ZMQ::MODE_SNDMORE); while (1) { $kvmsg = new Zmq_Kvmsg($sequence); $kvmsg->recv($snapshot); if ($kvmsg->key() == "KTHXBAI") { echo "I: received snapshot=" . $kvmsg->sequence() . "\n"; break; } } while (1) { $kvmsg = new Zmq_Kvmsg($sequence); $kvmsg->recv($sub_socket); echo "I: start receive sub=" . $kvmsg->sequence() . "\n"; $kvmsg->dump(); } return false; }
/** * @param $context * @param $endpoint * @return Zmsg */ private function createSubscriber($context, $endpoint) { $receiver = new \ZMQSocket($context, \ZMQ::SOCKET_SUB); $receiver->setSockOpt(\ZMQ::SOCKOPT_LINGER, 0); $receiver->setSockOpt(\ZMQ::SOCKOPT_SUBSCRIBE, ""); $receiver->connect($endpoint); return new Zmsg($receiver); }
/** * @param $context * @param $endpoint * @return Zmsg */ private function createCollector($context, $endpoint) { $receiver = new \ZMQSocket($context, \ZMQ::SOCKET_SUB); $receiver->setSockOpt(\ZMQ::SOCKOPT_LINGER, 0); $receiver->setSockOpt(\ZMQ::SOCKOPT_SUBSCRIBE, ""); $receiver->bind($endpoint); return $receiver; }
/** * @param $context * @param $endpoint * @return Zmsg */ private function createPublisher($context, $endpoint) { $publisher = new \ZMQSocket($context, \ZMQ::SOCKET_PUB); $publisher->setSockOpt(\ZMQ::SOCKOPT_SNDHWM, 1); $publisher->setSockOpt(\ZMQ::SOCKOPT_LINGER, 0); $publisher->bind($endpoint); return new Zmsg($publisher); }
/** * Connects or reconnect to broker * * @return AsynClient */ public function connect() { if ($this->client) { unset($this->client); } $this->client = new ZMQSocket($this->context, ZMQ::SOCKET_DEALER); $this->client->setSockOpt(ZMQ::SOCKOPT_LINGER, 0); $this->client->connect($this->broker); if ($this->verbose) { $this->log("ZMQDEBUG", "connecting to broker at %s...", $this->broker); } return $this; }
function s_worker_socket($context) { $worker = new ZMQSocket($context, ZMQ::SOCKET_DEALER); // Set random identity to make tracing easier $identity = sprintf("%04X-%04X", rand(0, 0x10000), rand(0, 0x10000)); $worker->setSockOpt(ZMQ::SOCKOPT_IDENTITY, $identity); $worker->connect("tcp://localhost:5556"); // Configure socket to not wait at close time $worker->setSockOpt(ZMQ::SOCKOPT_LINGER, 0); // Tell queue we're ready for work printf("I: (%s) worker ready%s", $identity, PHP_EOL); $worker->send("READY"); return array($worker, $identity); }
function client_task() { $context = new ZMQContext(); $client = new ZMQSocket($context, ZMQ::SOCKET_DEALER); // Generate printable identity for the client $identity = sprintf("%04X", rand(0, 0x10000)); $client->setSockOpt(ZMQ::SOCKOPT_IDENTITY, $identity); $client->connect("tcp://localhost:5570"); $read = $write = array(); $poll = new ZMQPoll(); $poll->add($client, ZMQ::POLL_IN); $request_nbr = 0; while (true) { // Tick once per second, pulling in arriving messages for ($centitick = 0; $centitick < 100; $centitick++) { $events = $poll->poll($read, $write, 1000); $zmsg = new Zmsg($client); if ($events) { $zmsg->recv(); printf("%s: %s%s", $identity, $zmsg->body(), PHP_EOL); } } $zmsg = new Zmsg($client); $zmsg->body_fmt("request #%d", ++$request_nbr)->send(); } }
/** * @param string|null $queueId * @param int $waitTime * * @return QueueMessage */ public function receiveMessage($queueId = null, $waitTime = null) { $queueId = empty($queueId) ? $this->getQueueId() : $queueId; $this->setupPullSocket($queueId); $this->pull->setSockOpt(\ZMQ::SOCKOPT_RCVTIMEO, isset($waitTime) ? $waitTime : $this->waitTime); $message = $this->pull->recv(); return $this->messageFactory->createMessage($message, $queueId); }
function client_socket(ZMQContext $context) { echo "I: connecting to server...", PHP_EOL; $client = new ZMQSocket($context, ZMQ::SOCKET_REQ); $client->connect("tcp://localhost:5555"); // Configure socket to not wait at close time $client->setSockOpt(ZMQ::SOCKOPT_LINGER, 0); return $client; }
public function pushActionResultInfo(ActionResultingPushDto $resultingPushDto) { $this->subscriberSocket->setSockOpt(\ZMQ::SOCKOPT_UNSUBSCRIBE, ""); $this->performerEarlyTerminated->setStandOnSubscription(false); $this->logger->debug("Performer was unsubscribed."); $this->initOrCheckPushConnection(); $this->pushSocket->send(serialize($resultingPushDto)); $this->logger->debug("Performer send actionResulting msg."); return null; }
function worker_task() { $context = new ZMQContext(); $worker = new ZMQSocket($context, ZMQ::SOCKET_DEALER); $worker->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "W"); $worker->connect("tcp://localhost:5556"); while (true) { $zmsg = new Zmsg($worker); $zmsg->recv(); $zmsg->send(); } }
public function handlerAction() { try { // setup the ZMQ content so as to avoid issues with conflicts $ctx = new \ZMQContext(); // create a SOCKET_REP server $server = new \ZMQSocket($ctx, \ZMQ::SOCKET_REP); // configure the server socket to not wait at close time // this is intended to minimise the possibility of messages being received and not handled // however as is mentioned in the TODO below they should be handle them explicitly $server->setSockOpt(\ZMQ::SOCKOPT_LINGER, 0); // bind it to tcp on port 5454 $server->bind('tcp://*:5454'); // create a Poll object to enable us to utilize the REQUEST_TIMEOUT functionality $poll = new \ZMQPoll(); $poll->add($server, \ZMQ::POLL_IN); // initialise the read/write buffers for polling $read = $write = array(); // get the time that we start the loop $start = time(); do { // this instruction will wait for a message or the timeout to occur $events = $poll->poll($read, $write, REQUEST_TIMEOUT); // @TODO since exiting the loop will happens after this point a race condition exists // We need to consider solutions that will ensure ALL messages to $server are processed // if the loop will exit after this iteration. // one could check the $events variable as this contains the number of events // however in this situation we only want to process the $read resources and can // just loop through an array (if it is empty nothing will be done) foreach ($read as $socket) { $message = $socket->recv(); $server->send($message . ' World'); } // ensure that even when a message is processed the handler // does not timeout until the REQUEST_TIMEOUT period // has elapsed $active = time() - $start < REQUEST_TIMEOUT / 1000.0; } while ($active); } catch (Exception $e) { // handle the exception // @TODO } // exit the handler die('This handler has timed out'); }
function subscriber() { $context = new ZMQContext(); // Subscribe to everything $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->connect("tcp://localhost:5556"); $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, ""); // Get and process messages while (true) { $clock = $subscriber->recv(); // Suicide snail logic if (microtime(true) * 100 - $clock * 100 > MAX_ALLOWED_DELAY) { echo "E: subscriber cannot keep up, aborting", PHP_EOL; break; } // Work for 1 msec plus some random additional time usleep(1000 + rand(0, 1000)); } }
<?php /* * Durable subscriber * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(1); // Connect our subscriber socket $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "Hello"); $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, ""); $subscriber->connect("tcp://localhost:5565"); // Synchronize with publisher $sync = new ZMQSocket($context, ZMQ::SOCKET_PUSH); $sync->connect("tcp://localhost:5564"); $sync->send(""); // Get updates, expect random Ctrl-C death while (true) { $string = $subscriber->recv(); echo $string, "\n"; if ($string == "END") { break; } }
<?php $context = new ZMQContext(); // Socket to talk to server echo "Collecting updates from weather server...", PHP_EOL; $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->connect("tcp://localhost:5556"); $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, 'Message'); // Process 100 updates while (true) { print $subscriber->recv(); }
<?php /* * Demonstrate identities as used by the request-reply pattern. Run this * program by itself. Note that the utility functions s_ are provided by * zhelpers.h. It gets boring for everyone to keep repeating this code. * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ include "zhelpers.php"; $context = new ZMQContext(); $sink = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $sink->bind("inproc://example"); // First allow 0MQ to set the identity $anonymous = new ZMQSocket($context, ZMQ::SOCKET_REQ); $anonymous->connect("inproc://example"); $anonymous->send("ROUTER uses a generated UUID"); s_dump($sink); // Then set the identity ourself $identified = new ZMQSocket($context, ZMQ::SOCKET_REQ); $identified->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "Hello"); $identified->connect("inproc://example"); $identified->send("ROUTER socket uses REQ's socket identity"); s_dump($sink);
#!/usr/bin/php <?php /** * Get generator status * * Usage: * * -p ZeroMQ port to connect to, default 5599 */ $opts = getopt('p:'); $port = isset($opts['p']) ? $opts['p'] : 5599; $context = new \ZMQContext(); $socket = new \ZMQSocket($context, \ZMQ::SOCKET_REQ); $socket->connect("tcp://localhost:{$port}"); $socket->setSockOpt(\ZMQ::SOCKOPT_LINGER, 0); $socket->send('STATUS'); $status = $socket->recv(); $status = json_decode($status, TRUE); echo "STATUS\n\n"; foreach ($status as $k => $v) { echo "{$k}\t{$v}\n"; } echo "\n";
<?php /* * Demonstrate identities as used by the request-reply pattern. Run this * program by itself. Note that the utility functions s_ are provided by * zhelpers.h. It gets boring for everyone to keep repeating this code. * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ include 'zhelpers.php'; $context = new ZMQContext(); $sink = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $sink->bind("inproc://example"); // First allow 0MQ to set the identity $anonymous = new ZMQSocket($context, ZMQ::SOCKET_REQ); $anonymous->connect("inproc://example"); $anonymous->send("ROUTER uses a generated UUID"); s_dump($sink); // Then set the identity ourselves $identified = new ZMQSocket($context, ZMQ::SOCKET_REQ); $identified->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "PEER2"); $identified->connect("inproc://example"); $identified->send("ROUTER socket uses REQ's socket identity"); s_dump($sink);
<?php /* * Reading from multiple sockets * This version uses zmq_poll() * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(); // Connect to task ventilator $receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL); $receiver->connect("tcp://localhost:5557"); // Connect to weather server $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->connect("tcp://localhost:5556"); $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, "10001"); // Initialize poll set $poll = new ZMQPoll(); $poll->add($receiver, ZMQ::POLL_IN); $poll->add($subscriber, ZMQ::POLL_IN); $readable = $writeable = array(); // Process messages from both sockets while (true) { $events = $poll->poll($readable, $writeable); if ($events > 0) { foreach ($readable as $socket) { if ($socket === $receiver) { $message = $socket->recv(); // Process task } elseif ($socket === $subscriber) { $mesage = $socket->recv(); // Process weather update
public function __destruct() { $this->socket->setSockOpt(ZMQ::SOCKOPT_LINGER, 0); $this->socket = null; $this->context = null; }
<?php /* * Cross-connected ROUTER sockets addressing each other * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ include "zhelpers.php"; $context = new ZMQContext(); $worker = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $worker->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "WORKER"); $worker->bind("ipc://rtrouter.ipc"); $server = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $server->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "SERVER"); $server->connect("ipc://rtrouter.ipc"); sleep(1); $server->send("WORKER", ZMQ::MODE_SNDMORE); $server->send("", ZMQ::MODE_SNDMORE); $server->send("send to worker"); s_dump($worker); $worker->send("SERVER", ZMQ::MODE_SNDMORE); $worker->send("", ZMQ::MODE_SNDMORE); $worker->send("send to server"); s_dump($server);
<?php /* * Weather update client * Connects SUB socket to tcp://localhost:5556 * Collects weather updates and finds avg temp in zipcode * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(); // Socket to talk to server echo "Collecting updates from weather server...", PHP_EOL; $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->connect("tcp://localhost:5556"); // Subscribe to zipcode, default is NYC, 10001 $filter = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : "10001"; $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $filter); // Process 100 updates $total_temp = 0; for ($update_nbr = 0; $update_nbr < 100; $update_nbr++) { $string = $subscriber->recv(); sscanf($string, "%d %d %d", $zipcode, $temperature, $relhumidity); $total_temp += $temperature; } printf("Average temperature for zipcode '%s' was %dF\n", $filter, (int) ($total_temp / $update_nbr));
/** * Unsubscribe socket from channel. * * @param mixed $channel */ public function unsubscribe($channel) { $this->socket->setSockOpt(ZMQ::SOCKOPT_UNSUBSCRIBE, $channel); }
<?php /* * Publisher for durable subscriber * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(1); // Subscriber tells us when it's ready here $sync = new ZMQSocket($context, ZMQ::SOCKET_PULL); $sync->bind("tcp://*:5564"); // We send updates via this socket $publisher = new ZMQSocket($context, ZMQ::SOCKET_PUB); // Prevent publisher overflow from slow subscribers $publisher->setSockOpt(ZMQ::SOCKOPT_HWM, 1); // Specify swap space in bytes, this covers all subscribers $publisher->setSockOpt(ZMQ::SOCKOPT_SWAP, 25000000); $publisher->bind("tcp://*:5565"); // Wait for synchronization request $string = $sync->recv(); // Now broadcast exactly 10 updates with pause for ($update_nbr = 0; $update_nbr < 10; $update_nbr++) { $string = sprintf("Update %d", $update_nbr); $publisher->send($string); sleep(1); } $publisher->send("END"); sleep(1); // Give 0MQ/2.0.x time to flush output
<?php /* * Simple Pirate worker * Connects REQ socket to tcp://*:5556 * Implements worker part of LRU queueing * * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ include 'zmsg.php'; $context = new ZMQContext(); $worker = new ZMQSocket($context, ZMQ::SOCKET_REQ); // Set random identity to make tracing easier $identity = sprintf("%04X-%04X", rand(0, 0x10000), rand(0, 0x10000)); $worker->setSockOpt(ZMQ::SOCKOPT_IDENTITY, $identity); $worker->connect("tcp://localhost:5556"); // Tell queue we're ready for work printf("I: (%s) worker ready%s", $identity, PHP_EOL); $worker->send("READY"); $cycles = 0; while (true) { $zmsg = new Zmsg($worker); $zmsg->recv(); $cycles++; // Simulate various problems, after a few cycles if ($cycles > 3 && rand(0, 3) == 0) { printf("I: (%s) simulating a crash%s", $identity, PHP_EOL); break; } elseif ($cycles > 3 && rand(0, 3) == 0) { printf("I: (%s) simulating CPU overload%s", $identity, PHP_EOL); sleep(5);
/* * Task worker - design 2 * Adds pub-sub flow to receive and respond to kill signal * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(); // Socket to receive messages on $receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL); $receiver->connect("tcp://localhost:5557"); // Socket to send messages to $sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH); $sender->connect("tcp://localhost:5558"); // Socket for control input $controller = new ZMQSocket($context, ZMQ::SOCKET_SUB); $controller->connect("tcp://localhost:5559"); $controller->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, ""); // Process messages from receiver and controller $poll = new ZMQPoll(); $poll->add($receiver, ZMQ::POLL_IN); $poll->add($controller, ZMQ::POLL_IN); $readable = $writeable = array(); // Process messages from both sockets while (true) { $events = $poll->poll($readable, $writeable); if ($events > 0) { foreach ($readable as $socket) { if ($socket === $receiver) { $message = $socket->recv(); // Simple progress indicator for the viewer echo $message, PHP_EOL; // Do the work
<?php try { $context = new \ZMQContext(); $subscriber = new \ZMQSocket($context, \ZMQ::SOCKET_SUB); $subscriber->connect("tcp://127.0.0.1:5556"); $subscriber->setSockOpt(\ZMQ::SOCKOPT_SUBSCRIBE, 'log-channel'); while (true) { $msg = $subscriber->recv(); if ($msg == 'log-channel') { printf("printing logs for channel %s \n", $msg); } else { var_dump(json_decode($msg)); } } } catch (\Exception $e) { echo $e->getMessage(); }
public function multiple_readerAction() { $context = new ZMQContext(); $receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL); $receiver->connect("tcp://127.0.0.1:5557"); $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->connect("tcp://127.0.0.1:5556"); $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, "10001"); while (true) { try { for ($rc = 0; !$rc;) { if ($rc = $receiver->recv(ZMQ::MODE_NOBLOCK)) { // process task } } } catch (ZMQSocketException $e) { //do nothing } try { for ($rc = 0; !$rc;) { if ($rc = $receiver->recv(ZMQ::MODE_NOBLOCK)) { // process task } } } catch (ZMQSocketException $e) { //do nothing } usleep(1); } }
<?php /* * Weather proxy device * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(); // This is where the weather server sits $frontend = new ZMQSocket($context, ZMQ::SOCKET_SUB); $frontend->connect("tcp://192.168.55.210:5556"); // This is our public endpoint for subscribers $backend = new ZMQSocket($context, ZMQ::SOCKET_PUB); $backend->bind("tcp://10.1.1.0:8100"); // Subscribe on everything $frontend->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, ""); // Shunt messages out to our own subscribers while (true) { while (true) { // Process all parts of the message $message = $frontend->recv(); $more = $frontend->getSockOpt(ZMQ::SOCKOPT_RCVMORE); $backend->send($message, $more ? ZMQ::MODE_SNDMORE : 0); if (!$more) { break; // Last message part } } }
<?php /* * Custom routing Router to Papa (ROUTER to REP) * @author Ian Barber <ian(dot)barber(at)gmail(dot)com>a */ include "zhelpers.php"; // We will do this all in one thread to emphasize the sequence // of events... $context = new ZMQContext(); $client = new ZMQSocket($context, ZMQ::SOCKET_ROUTER); $client->bind("inproc://routing"); $worker = new ZMQSocket($context, ZMQ::SOCKET_REP); $worker->setSockOpt(ZMQ::SOCKOPT_IDENTITY, "A"); $worker->connect("inproc://routing"); // Send papa address, address stack, empty part, and request $client->send("A", ZMQ::MODE_SNDMORE); $client->send("address 3", ZMQ::MODE_SNDMORE); $client->send("address 2", ZMQ::MODE_SNDMORE); $client->send("address 1", ZMQ::MODE_SNDMORE); $client->send("", ZMQ::MODE_SNDMORE); $client->send("This is the workload"); // Worker should get just the workload s_dump($worker); // We don't play with envelopes in the worker $worker->send("This is the reply"); // Now dump what we got off the ROUTER socket... s_dump($client);