Goto Chapter: Top 1 2 3 Ind
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 

2 ZeroMQ Bindings
 2.1 Addresses, transports, and URIs
 2.2 Creating and closing sockets
 2.3 Binding and connecting sockets to addresses
 2.4 Sending and receiving messages
 2.5 Setting and querying socket properties

2 ZeroMQ Bindings

There are experimental bindings to the ZeroMQ library available http://www.zeromq.net/. This section describes these bindings. Messages in ZeroMQ are sent between endpoints called sockets. Each socket can be bound to an address specified by a URI and other sockets can connect to the same address to exchange messages with that socket.

2.1 Addresses, transports, and URIs

Addresses are specified as URIs of one of four different types (TCP, IPC, in-process, PGM/EPGM), each for a different type of transport.

2.1-1 The TCP transport

TCP URIs map to POSIX TCP stream sockets. The URI is of the form tcp://<address>:<port> or tcp://*:<port>. Here, address is an internet address, either an IP address or a symbolic address (note that to resolve symbolic addresses, the library may have to consult DNS servers, which can take an indefinite amount of time or even fail). Port is a TCP port number. If a "*" is given instead of an address, this describes the so-called unspecified address; the URI can only be used for binding and will then accept incoming connections from all interfaces (as in binding to "0.0.0.0" in IPv4 or "::" in IPv6).

2.1-2 The IPC transport

The URI for IPC communication is of the form ipc://<path>, where path is an actual path on the file system. Binding to such a URI will create a file in that location.

gap> socket := ZmqDealerSocket();;
gap> ZmqBind(socket, "ipc:///tmp/connector");

2.1-3 The in-process transport

The in-process transport is used to communicate between threads in order to avoid the overhead of operating system calls. Messages are simply being copied from one thread's memory to the other's. In-process URIs are of the form inproc://<string>, where string is an arbitrary string.

2.2 Creating and closing sockets

Sockets are generally being created via calls to ZmqPushSocket (2.2-1), etc. Each such call takes two optional arguments, a URI and an identity. If a URI is given, a call to ZmqAttach (2.3-3) will be performed immediately with the socket and URI. In particular, if the URI is prefixed with a "+" character, then the socket will connect to the address specified by the part after the "+" character; otherwise, it will be bound to the URI.

gap> z := ZmqPushSocket("inproc://test");  # binds to inproc://test
gap> z := ZmqPushSocket("+inproc://test"); # connects to inproc://test

If an identity is also provided, the library will call ZmqSetIdentity (2.5-1) to set the identity (name) for that socket. For a precise description of the behavior of each socket type, please consult the original ZeroMQ documentation for zmq_socket().

2.2-1 ZmqPushSocket
‣ ZmqPushSocket( [uri[, identity]] )( function )

A push socket is one end of a unidirectional pipe. Programs can send messages to it, which will be delivered to a matched pull socket at the other end.

2.2-2 ZmqPullSocket
‣ ZmqPullSocket( [uri[, identity]] )( function )

A pull socket is the other end of a unidirectional pipe.

2.2-3 ZmqReplySocket
‣ ZmqReplySocket( [uri[, identity]] )( function )

A reply socket provides the server side of a remote-procedure call interaction. It alternates between receiving a message and sending a message to the socket from which the previous one originated. Deviating from that protocol (for example, by sending two messages in succession or receiving two without responding to the first) will result in an error.

2.2-4 ZmqRequestSocket
‣ ZmqRequestSocket( [uri[, identity]] )( function )

A request socket provides the client side of a remote-procedure call interaction. It will alternate between sending a message to a connected reply socket and receiving the response.

2.2-5 ZmqPublisherSocket
‣ ZmqPublisherSocket( [uri[, identity]] )( function )

A publisher socket is a unidirectional broadcast facility. It will send each outgoing message to all connected subscriber sockets.

2.2-6 ZmqSubscriberSocket
‣ ZmqSubscriberSocket( [uri[, identity]] )( function )

A subscriber socket receives messages from a publisher socket. It can subscribe to only a specific subseet of messages (see the ZmqSubscribe (2.5-11) function) or receive all of them.

2.2-7 ZmqDealerSocket
‣ ZmqDealerSocket( [uri[, identity]] )( function )

A dealer socket is a bidirectional socket. One or more peers can connect to it. Outgoing messages will be sent to those peers in a round-robin fashion (i.e., the first message goes to the first peer, the second to the second peer, and so forth until all peers have received a message and the process begins anew with the first peer). Incoming messages will be received from all peers and processed fairly (i.e., no message will be held indefinitely). Two dealer sockets can be used to create a bidirectional pipe.

2.2-8 ZmqRouterSocket
‣ ZmqRouterSocket( [uri[, identity]] )( function )

Router sockets, like dealer sockets, can have multiple peers connected to them. Incoming messages are handled the same way as for dealer sockets. Outgoing messages should be multi-part messages, where the first part of the message is the identity of one of the peers. The message will then be sent only to the peer with that identity. Peers can be dealer, request, or reply sockets.

2.2-9 ZmqSocket
‣ ZmqSocket( type )( function )

ZmqSocket is a low-level function that is used by ZmqPushSocket etc. to create sockets. Its argument is a string, one of "PUSH", "PULL", "REP", "REQ", "PUB", "SUB", "DEALER", "ROUTER", and it creates and returns a socket of that type.

2.2-10 ZmqClose
‣ ZmqClose( socket )( function )

ZmqClose closes socket. Afterwards, it cannot anymore be bound or connected to, nor receive or send messages. Messages already in transit will still be delivered.

2.2-11 ZmqIsOpen
‣ ZmqIsOpen( socket )( function )

ZmqIsOpen returns true if socket has not been closed yet, false otherwise.

2.2-12 ZmqSocketType
‣ ZmqSocketType( socket )( function )

ZmqSocketType returns the string with which the socket was created (see ZmqSocket (2.2-9)).

2.3 Binding and connecting sockets to addresses

2.3-1 ZmqBind
‣ ZmqBind( socket, uri )( function )

ZmqBind will bind socket to uri. After being bound to the address specified by uri, the socket can be connected to at that address with ZmqConnect (2.3-2).

2.3-2 ZmqConnect
‣ ZmqConnect( socket, uri )( function )

ZmqConnect is used to connect socket to another socket that has been bound to uri. Note that you can connect to an address that has not been bound yet; in that case, the connection will be delayed until the binding has occurred.

2.3-3 ZmqAttach
‣ ZmqAttach( socket, uri )( function )

ZmqAttach is a unified interface for binding and connecting a socket. If uri begins with a "+" character, then the ZmqConnect (2.3-2) is called with the socket and the rest of the uri string following the "+". Otherwise, ZmqBind (2.3-1) is called with these arguments. The intended use is to construct a network of connections from a list of strings.

2.3-4 ZmqSocketURI
‣ ZmqSocketURI( socket )( function )

ZmqSocketURI returns the most recent URI to which socket has been bound or connected. Sockets can be bound to or connected to multiple addresses, but only the most recent one is returned.

2.3-5 ZmqIsBound
‣ ZmqIsBound( socket )( function )

ZmqIsBound returns true if the socket has been bound to the address returned by ZmqSocketURI(), false otherwise.

2.3-6 ZmqIsConnected
‣ ZmqIsConnected( socket )( function )

ZmqIsBound returns true if the socket has been connected to the address returned by ZmqSocketURI(), false otherwise.

2.4 Sending and receiving messages

ZeroMQ allows the sending and receiving of both string messages and multi-part messages. String messages are sequences of bytes (which can include zero), provided as a GAP string, while multi-part messages are lists of strings, provided as a GAP list. Multi-part messages are largely a convenience feature (e.g., to allow a message to have header parts without the inconvenience of having to encode those in a single string). When sent, multi-part messages will be delivered in their entirety; they can be retrieved one part at a time, but if the first part is available, the last part is available also.

2.4-1 ZmqSend
‣ ZmqSend( socket, data )( function )

ZmqSend will send data to socket, according to the routing behavior of the underlying socket mechanism.

2.4-2 ZmqReceive
‣ ZmqReceive( socket )( function )

ZmqReceive will either retrieve a string message or a single part of a multi-part message from socket and return the result as a GAP string.

gap> z := ZmqSocket("inproc://test");;
gap> z2 := ZmqSocket("+inproc://test");;
gap> ZmqSend(z, "notice");
gap> ZmqReceive(z2);
"notice"
gap> ZmqSend(z, ["alpha", "beta"]);
gap> ZmqReceive(z2);
"alpha"
gap> ZmqReceive(z2);
"beta"

2.4-3 ZmqReceiveList
‣ ZmqReceiveList( socket )( function )

ZmqReceiveList will retrieve a message in its entirety from socket and return the result as a list of strings.

gap> z := ZmqPushSocket("inproc://test");;
gap> z2 := ZmqPullSocket("+inproc://test");;
gap> ZmqSend(z, "notice");
gap> ZmqReceiveList(z2);
[ "notice" ]
gap> ZmqSend(z, ["alpha", "beta"]);
gap> ZmqReceiveList(z2);
[ "alpha", "beta" ]

2.4-4 ZmqReceiveListAsString
‣ ZmqReceiveListAsString( socket, separator )( function )

ZmqReceiveListAsString works like ZmqReceiveList, but will return the result a single string, with multiple parts separated by separator.

gap> z := ZmqPushSocket("inproc://test");;
gap> z2 := ZmqPullSocket("+inproc://test");;
gap> ZmqSend(z, "notice");
gap> ZmqReceiveListAsString(z2, "::");
"notice"
gap> ZmqSend(z, ["alpha", "beta"]);
gap> ZmqReceiveListAsString(z2, "::");
"alpha::beta"

2.4-5 ZmqHasMore
‣ ZmqHasMore( socket )( function )

ZmqHasMore will return true if a socket has one or more remaining parts of a multi-part message outstanding, false otherwise.

gap> z := ZmqPushSocket("inproc://test");;
gap> z2 := ZmqPullSocket("+inproc://test");;
gap> ZmqSend(z, "notice");
gap> ZmqReceive(z2);
"notice"
gap> ZmqHasMore(z2);
false
gap> ZmqSend(z, ["alpha", "beta"]);
gap> ZmqReceive(z2);
"alpha"
gap> ZmqHasMore(z2);
true
gap> ZmqReceive(z2);
"beta"
gap> ZmqHasMore(z2);
false

2.4-6 ZmqPoll
‣ ZmqPoll( inputs, outputs, timeout )( function )

ZmqPoll is a facility to determine if messages can be received from one of the sockets listed in inputs or sent to one of the sockets listed in outputs. It returns a list of indices describing the sockets that at least one message can be received from or sent to. The timeout is an integer. If positive, it describes a duration (in milliseconds) after which it will return. If zero, the function will return immediately. If it is -1, then the function will block indefinitely until at least one message can be retrieved from one of the sockets in inputs or at least one message can be sent to one of the sockets in outputs. If the timeout is non-negative, the result can be the empty list. It is guaranteed to have at least one element otherwise. The indices in the result are in the range [1..Length(inputs)+Length(outputs). An index i less than or equal to Length(inputs) refers to the socket inputs[i]. An index j in the range [Length(inputs)+1..Length(inputs)+Length(outputs) refers to the socket outputs[j-Length(inputs)]. Multiple indices are listed in ascending order (i.e., they form a GAP set).

gap> send1 := ZmqPushSocket("inproc://#1");;
gap> recv1 := ZmqPullSocket("+inproc://#1");;
gap> send2 := ZmqPushSocket();;
gap> recv2 := ZmqPullSocket();;
gap> ZmqSetSendCapacity(send2, 1);
gap> ZmqSetReceiveCapacity(recv2, 1);
gap> ZmqBind(send2, "inproc://#2");
gap> ZmqConnect(recv2, "inproc://#2");
gap> ZmqSend(send2, "alpha");
gap> ZmqSend(send2, "beta");
gap> ZmqPoll([recv1, recv2], [send1, send2], 0);
[ 2, 3 ]

In the example above, the code constructs sockets send2 and recv2 with a capacity to store at most one outgoing and incoming message, respectively. Then the code sends two messages to send2, one of which will be in the incoming buffer of recv2, and the other will remain in the outgoing buffer of send2. At this point, no more messages can be sent to send2, because its outgoing buffer is at capacity, and recv2 has a message that can be received. Conversely, send1 can still accept outgoing messages, and recv1 has no messages. Thus, the result is the list [2, 3]. The 2 refers to recv2 (as the second socket in the list of inputs), while 3 refers to send1 (as the first socket in the list of outputs).

2.5 Setting and querying socket properties

Sockets have properties that can be set and queried. Most such properties only affect binds and connects that occur after they have been set. Binding or connecting a socket first and then setting a property will not change the behavior of the socket.

2.5-1 ZmqSetIdentity
‣ ZmqSetIdentity( socket, string )( function )

ZmqSetIdentity can be used to give the socket an identity. An identity is a string of up to 255 characters that should not start with a null character (the null character is reserved for internal use). This identity should be globally unique. Uniqueness is not enforced, however, and undefined behavior may result from different sockets with the same identity interacting.

2.5-2 ZmqGetIdentity
‣ ZmqGetIdentity( socket )( function )

ZmqGetIdentity returns the current identity of the socket.

2.5-3 ZmqSetSendCapacity
‣ ZmqSetSendCapacity( socket, value )( function )

ZmqSetSendCapacity sets the maximum number of messages that a socket can store in its outgoing buffer.

2.5-4 ZmqSetReceiveCapacity
‣ ZmqSetReceiveCapacity( socket, value )( function )

ZmqSetReceiveCapacity sets the maximum number of messages that a socket can store in its outgoing buffer.

2.5-5 ZmqGetSendCapacity
‣ ZmqGetSendCapacity( socket )( function )

ZmqGetSendCapacity returns the maximum number of messages that a socket can store in its outgoing buffer.

2.5-6 ZmqGetReceiveCapacity
‣ ZmqGetReceiveCapacity( socket )( function )

ZmqGetReceiveCapacity returns the maximum number of messages that a socket can store in its incoming buffer.

2.5-7 ZmqSetSendBufferSize
‣ ZmqSetSendBufferSize( socket, size )( function )

ZmqSetSendBufferSize sets the size of the transmission buffer used by the underlying operating system structure for sending data.

2.5-8 ZmqGetSendBufferSize
‣ ZmqGetSendBufferSize( socket )( function )

ZmqGetSendBufferSize returns the size of the transmission buffer used by the underlying operating system structure for sending data.

2.5-9 ZmqSetReceiveBufferSize
‣ ZmqSetReceiveBufferSize( socket, size )( function )

ZmqSetReceiveBufferSize sets the size of the transmission buffer used by the underlying operating system structure for receiving data.

2.5-10 ZmqGetReceiveBufferSize
‣ ZmqGetReceiveBufferSize( socket )( function )

ZmqGetReceiveBufferSize returns the size of the transmission buffer used by the underlying operating system structure for receiving data.

2.5-11 ZmqSubscribe
‣ ZmqSubscribe( socket, prefix )( function )

The ZmqSubscribe function can only be used for Subscriber sockets. After calling it, only messages that begin with the given prefix string will be received by the subscriber. All others will be silently discarded. The function can be used multiple times, and then all messages that match any of the prefixes will be received.

2.5-12 ZmqUnsubscribe
‣ ZmqUnsubscribe( socket, prefix )( function )

The ZmqUnsubscribe function removes the given prefix string from the socket's subscription list.

 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 
Goto Chapter: Top 1 2 3 Ind

generated by GAPDoc2HTML