Zeromq package
The zeromq package is part of the Octave Forge project and provides Octave bindings to the ZeroMQ library.
Installation
package requirements
The zeromq package requires the ZeroMQ libraries and include files to be installed in order to compile.
for fedora: yum install zeromq-devel
for ubuntu: apt install libzmq-dev
octave installation
With the ZeroMQ library installed, from octave commmand line:
>> pkg install -forge zeromq
Using it
Load it before any usage:
>> pkg load zeromq
Look at the quick reference for the package:
>> help zeromq
Differences between C and Octave bindings
The Octave binding is a subset of the C binding of the ZeroMQ library.
Major differences are:
1. The octave binding creates a single zeromq context that is used for all zeromq sockets. In the C bindings, the programmer must create a context and use it during socket creation.
2. only limited zmq_getsockopt and zmq_setsockopt is currently implemented.
3. functions mostly return true or false for whether they succeeded or failed. In the C binding, 0 signified success.
The functions
zmq_bind Bind a zeromq socket to a endpoint.
zmq_close Close a zeromq socket.
zmq_connect Connect a zeromq socket to a endpoint
zmq_errno Get system errno value.
zmq_getsockopt Get current value of a zeromq socket option.
zmq_poll Poll a socket or sockets for a timeout or incoming data available.
zmq_recv Attempt to read data from a zeromq socket.
zmq_send Attempt to send data from a zeromq socket.
zmq_setsockopt Set a zeromq socket option.
zmq_strerror Get the last zmq error string.
zmq_unbind Unbind a previously bound zeromq socket.
zmq_version Get the zeromq library version numbers.
Examples
The zeromq package comes with a number of examples included in it. They can be opened in octave using:
>> edit examples/zmq_example1.m
basic request/reply pattern
Example based on client/server example from http://zguide.zeromq.org/page:all#Ask-and-Ye-Shall-Receive
The client sends a "Hello" to the server which responds back "World". No error checking or data validation is done in the example.
Code: Server code |
% zeromq package must be installed and loaded to work
pkg load zeromq
% dont buffer output
more off
printf ("Creating hello world server...\n");
% create reply socket, and bind it to port 5555
sock = zmq_socket (ZMQ_REP);
zmq_bind (sock, "tcp://*:5555");
printf ("Waiting for clients ...\n");
% loop forever, waiting for client requests and responding back
while (true)
recievedata = zmq_recv (sock, 10, 0);
printf ("Received Hello\n");
zmq_send (sock, "World", 5, 0);
endwhile
|
Code: Client code |
% zeromq package must be installed and loaded to work
pkg load zeromq
% dont buffer output
more off
printf ("Connecting to hello world server...\n");
% Create socket and connect to server
sock = zmq_socket (ZMQ_REQ);
zmq_connect (sock, "tcp://localhost:5555");
for request_nbr = [1:10]
printf ("Sending Hello %d...\n", request_nbr);
zmq_send (sock, uint8("Hello"), 5, 0);
% try to read up to 10 bytes of reply data.
printf ("Waiting for server response %d... (Ctrl-C to exit)\n", request_nbr);
recieved = zmq_recv (sock, 10, 0);
printf ("Received World %d\n", request_nbr);
endfor
zmq_close (sock);
|
basic publish/subscribe pattern
Example based on client/server example from http://zguide.zeromq.org/page:all#Getting-the-Message-Out
The server pushes 'weather updates' for random zipcodes. The client subscribes to the server just for zipcode 10001.
Code: Server code |
% zeromq package must be installed and loaded to work
pkg load zeromq
% dont buffer output
more off
publisher = zmq_socket (ZMQ_PUB);
rc = zmq_bind (publisher, "tcp://*:5556");
assert (rc);
while (true)
% Get values that will fool the boss
zipcode = 10000 + randi (20);
temperature = randi (215) - 80;
relhumidity = randi (50) + 10;
% Send message to all subscribers
update = sprintf ("%05d %d %d", zipcode, temperature, relhumidity);
zmq_send (publisher, update);
endwhile
zmq_close (publisher);
|
Code: Client code |
% zeromq package must be installed and loaded to work
pkg load zeromq
% dont buffer output
more off
subscriber = zmq_socket (ZMQ_SUB);
rc = zmq_connect (subscriber, "tcp://localhost:5556");
assert (rc);
% Subscribe to zipcode, default is NYC, 10001
zipfilter = "10001 ";
rc = zmq_setsockopt (subscriber, ZMQ_SUBSCRIBE, zipfilter);
assert (rc);
% Process 100 updates
update_nbr = 0;
total_temp = 0;
for update_nbr = 1:100
string = char( zmq_recv(subscriber, 128) );
[zipcode, temperature, relhumidity, count, errmsg] = sscanf (string, "%d %d %d", "C");
fprintf ("recieved a temp for zipcode '%s' of %dF\n", ...
zipfilter, temperature);
total_temp += temperature;
endfor
fprintf ("Average temperature for zipcode '%s' was %dF\n", ...
zipfilter, (total_temp / update_nbr));
zmq_close (subscriber);
|