<Chapter Label="ZeroMQ Bindings">
<Heading>ZeroMQ Bindings</Heading>

There are experimental bindings to the ZeroMQ library available <URL>http://www.zeromq.net/</URL>. This section describes these
bindings.

Messages in ZeroMQ are sent between endpoints called <E>sockets</E>. Each socket can be <E>bound</E> to an address
specified by a URI and other sockets can <E>connect</E> to the same address to exchange messages with that socket.

<Section Label="Addresses, transports, and URIs">
<Heading>Addresses, transports, and URIs</Heading>

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

<Subsection Label="The TCP transport"><Heading>The TCP transport</Heading>

TCP URIs map to POSIX TCP stream sockets. The URI is of the form <C>tcp://&lt;address&gt;:&lt;port&gt;</C> or
<C>tcp://*:&lt;port&gt;</C>. Here, <C>address</C> 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 <Q>*</Q> 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 <Q>0.0.0.0</Q> in IPv4 or <Q>::</Q> in IPv6).

</Subsection>
<Subsection Label="The IPC transport">
<Heading>The IPC transport</Heading>

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

<Example><![CDATA[
gap> socket := ZmqDealerSocket();;
gap> ZmqBind(socket, "ipc:///tmp/connector");
]]></Example>

</Subsection>
<Subsection Label="The in-process transport">
<Heading>The in-process transport</Heading>

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 <C>inproc://&lt;string&gt;</C>, where <C>string</C> is an arbitrary string.
</Subsection>
</Section>

<Section Label="Creating and closing sockets">
<Heading>Creating and closing sockets</Heading>

Sockets are generally being created via calls to <Ref Func="ZmqPushSocket"/>, etc. Each such call takes two optional
arguments, a URI and an identity.

If a URI is given, a call to <Ref Func="ZmqAttach"/> will be performed immediately with the socket and URI. In
particular, if the URI is prefixed with a <Q>+</Q> character, then the socket will connect to the address specified
by the part after the <Q>+</Q> character; otherwise, it will be bound to the URI.

<Example><![CDATA[
gap> z := ZmqPushSocket("inproc://test");  # binds to inproc://test
gap> z := ZmqPushSocket("+inproc://test"); # connects to inproc://test
]]></Example>

If an identity is also provided, the library will call <Ref Func="ZmqSetIdentity"/> 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
<C>zmq_socket()</C>.

<ManSection>
<Func Name="ZmqPushSocket" Arg="[uri, [identity]]"/>
<Description>
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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqPullSocket" Arg="[uri, [identity]]"/>
<Description>
A pull socket is the other end of a unidirectional pipe.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqReplySocket" Arg="[uri, [identity]]"/>
<Description>
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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqRequestSocket" Arg="[uri, [identity]]"/>
<Description>
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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqPublisherSocket" Arg="[uri, [identity]]"/>
<Description>
A publisher socket is a unidirectional broadcast facility. It will send each outgoing message to all connected
subscriber sockets.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSubscriberSocket" Arg="[uri, [identity]]"/>
<Description>
A subscriber socket receives messages from a publisher socket. It can subscribe to only a specific subseet of messages
(see the <Ref Func="ZmqSubscribe"/> function) or receive all of them.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqDealerSocket" Arg="[uri, [identity]]"/>
<Description>
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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqRouterSocket" Arg="[uri, [identity]]"/>
<Description>
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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSocket" Arg="type"/>
<Description>
<C>ZmqSocket</C> is a low-level function that is used by <C>ZmqPushSocket</C> etc. to create sockets. Its argument is a
string, one of <Q>PUSH</Q>, <Q>PULL</Q>, <Q>REP</Q>, <Q>REQ</Q>, <Q>PUB</Q>, <Q>SUB</Q>,
<Q>DEALER</Q>, <Q>ROUTER</Q>, and it creates and returns a socket of that type.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqClose" Arg="socket"/>
<Description>
<C>ZmqClose</C> closes <C>socket</C>. Afterwards, it cannot anymore be bound or connected to, nor receive or send
messages. Messages already in transit will still be delivered.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqIsOpen" Arg="socket"/>
<Description>
<C>ZmqIsOpen</C> returns true if <C>socket</C> has not been closed yet, false otherwise.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSocketType" Arg="socket"/>
<Description>
<C>ZmqSocketType</C> returns the string with which the socket was created (see <Ref Func="ZmqSocket"/>).
</Description>
</ManSection>

</Section>

<Section Label="Binding and connecting sockets to addresses">
<Heading>Binding and connecting sockets to addresses</Heading>

<ManSection>
<Func Name="ZmqBind" Arg="socket, uri"/>
<Description>
<C>ZmqBind</C> will <E>bind</E> <C>socket</C> to <C>uri</C>. After being bound to the address specified by <C>uri</C>,
the socket can be connected to at that address with <Ref Func="ZmqConnect"/>.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqConnect" Arg="socket, uri"/>
<Description>
<C>ZmqConnect</C> is used to connect <C>socket</C> to another socket that has been bound to <C>uri</C>. 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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqAttach" Arg="socket, uri"/>
<Description>
<C>ZmqAttach</C> is a unified interface for binding and connecting a socket. If <C>uri</C> begins with a <Q>+</Q>
character, then the <Ref Func="ZmqConnect"/> is called with the socket and the rest of the <C>uri</C> string following
the <Q>+</Q>. Otherwise, <Ref Func="ZmqBind"/> is called with these arguments.

The intended use is to construct a network of connections from a list of strings.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSocketURI" Arg="socket"/>
<Description>
<C>ZmqSocketURI</C> returns the most recent URI to which <C>socket</C> has been bound or connected. Sockets can be bound
to or connected to multiple addresses, but only the most recent one is returned.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqIsBound" Arg="socket"/>
<Description>
<C>ZmqIsBound</C> returns true if the socket has been bound to the address returned by <C>ZmqSocketURI()</C>, false
otherwise.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqIsConnected" Arg="socket"/>
<Description>
<C>ZmqIsBound</C> returns true if the socket has been connected to the address returned by <C>ZmqSocketURI()</C>, false
otherwise.
</Description>
</ManSection>

</Section>

<Section Label="Sending and receiving messages">
<Heading>Sending and receiving messages</Heading>

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.

<ManSection>
<Func Name="ZmqSend" Arg="socket, data"/>
<Description>
<C>ZmqSend</C> will send <C>data</C> to <C>socket</C>, according to the routing behavior of the underlying socket
mechanism.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqReceive" Arg="socket"/>
<Description>
<C>ZmqReceive</C> will either retrieve a string message or a single part of a multi-part message from <C>socket</C> and
return the result as a GAP string.

<Example><![CDATA[
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"
]]></Example>
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqReceiveList" Arg="socket"/>
<Description>
<C>ZmqReceiveList</C> will retrieve a message in its entirety from <C>socket</C> and return the result as a list of
strings.

<Example><![CDATA[
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" ]
]]></Example>
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqReceiveListAsString" Arg="socket, separator"/>
<Description>
<C>ZmqReceiveListAsString</C> works like <C>ZmqReceiveList</C>, but will return the result a single string, with
multiple parts separated by <C>separator</C>.

<Example><![CDATA[
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"
]]></Example>
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqHasMore" Arg="socket"/>
<Description>
<C>ZmqHasMore</C> will return <C>true</C> if a socket has one or more remaining parts of a multi-part message
outstanding, <C>false</C> otherwise.

<Example><![CDATA[
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
]]></Example>
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqPoll" Arg="inputs, outputs, timeout"/>
<Description>
<C>ZmqPoll</C> is a facility to determine if messages can be received from one of the sockets listed in <C>inputs</C> or
sent to one of the sockets listed in <C>outputs</C>. 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 <C>-1</C>, then the
function will block indefinitely until at least one message can be retrieved from one of the sockets in <C>inputs</C> or
at least one message can be sent to one of the sockets in <C>outputs</C>. 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 <C>[1..Length(inputs)+Length(outputs)</C>. An index <C>i</C> less than or
equal to <C>Length(inputs)</C> refers to the socket <C>inputs[i]</C>. An index <C>j</C> in the range
<C>[Length(inputs)+1..Length(inputs)+Length(outputs)</C> refers to the socket <C>outputs[j-Length(inputs)]</C>. Multiple
indices are listed in ascending order (i.e., they form a GAP set).

<Example><![CDATA[
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 ]
]]></Example>

In the example above, the code constructs sockets <C>send2</C> and <C>recv2</C> with a capacity to store at most one
outgoing and incoming message, respectively. Then the code sends two messages to <C>send2</C>, one of which will be in
the incoming buffer of <C>recv2</C>, and the other will remain in the outgoing buffer of <C>send2</C>. At this point, no
more messages can be sent to <C>send2</C>, because its outgoing buffer is at capacity, and <C>recv2</C> has a message
that can be received. Conversely, <C>send1</C> can still accept outgoing messages, and <C>recv1</C> has no messages.

Thus, the result is the list <C>[2, 3]</C>. The <C>2</C> refers to <C>recv2</C> (as the second socket in the list of
inputs), while <C>3</C> refers to <C>send1</C> (as the first socket in the list of outputs).
</Description>
</ManSection>

</Section>

<Section Label="Setting and querying socket properties">
<Heading>Setting and querying socket properties</Heading>

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.

<ManSection>
<Func Name="ZmqSetIdentity" Arg="socket, string"/>
<Description>
<C>ZmqSetIdentity</C> 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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqGetIdentity" Arg="socket"/>
<Description>
<C>ZmqGetIdentity</C> returns the current identity of the socket.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSetSendCapacity" Arg="socket, value"/>
<Description>
<C>ZmqSetSendCapacity</C> sets the maximum number of messages that a socket can store in its outgoing buffer.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSetReceiveCapacity" Arg="socket, value"/>
<Description>
<C>ZmqSetReceiveCapacity</C> sets the maximum number of messages that a socket can store in its outgoing buffer.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqGetSendCapacity" Arg="socket"/>
<Description>
<C>ZmqGetSendCapacity</C> returns the maximum number of messages that a socket can store in its outgoing buffer.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqGetReceiveCapacity" Arg="socket"/>
<Description>
<C>ZmqGetReceiveCapacity</C> returns the maximum number of messages that a socket can store in its incoming buffer.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSetSendBufferSize" Arg="socket, size"/>
<Description>
<C>ZmqSetSendBufferSize</C> sets the size of the transmission buffer used by the underlying operating system structure
for sending data.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqGetSendBufferSize" Arg="socket"/>
<Description>
<C>ZmqGetSendBufferSize</C> returns the size of the transmission buffer used by the underlying operating system
structure for sending data.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSetReceiveBufferSize" Arg="socket, size"/>
<Description>
<C>ZmqSetReceiveBufferSize</C> sets the size of the transmission buffer used by the underlying operating system
structure for receiving data.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqGetReceiveBufferSize" Arg="socket"/>
<Description>
<C>ZmqGetReceiveBufferSize</C> returns the size of the transmission buffer used by the underlying operating system
structure for receiving data.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqSubscribe" Arg="socket, prefix"/>
<Description>
The <C>ZmqSubscribe</C> 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.
</Description>
</ManSection>

<ManSection>
<Func Name="ZmqUnsubscribe" Arg="socket, prefix"/>
<Description>
The <C>ZmqUnsubscribe</C> function removes the given prefix string from the socket's subscription list.
</Description>
</ManSection>

</Section>
</Chapter>
