ZeroMQ: Distributed Messaging (original) (raw)

8.15

This library provides bindings to theZeroMQ (or “0MQ”, or “ZMQ”) distributed messaging library.

This package is distributed under theGNU Lesser General Public License (LGPL). As a client of this library you must also comply with the libzmq license.

1 ZeroMQ Examples🔗

This section contains examples of using this library adapted from the0MQ Guide.

1.1 Hello World in ZeroMQ🔗

This example is adapted fromAsk and Ye Shall Receive, which illustrates REP-REQ communication.

Here is the “hello world” server:

The responder socket could have been created and connected to its address in one call, as follows:

(define responder (zmq-socket 'rep #:bind "tcp://*:5555"))

Here is the “hello world” client:

> (define requester (zmq-socket 'req #:connect "tcp://localhost:5555"))
> (for ([request-number (in-range 3)]) (zmq-send requester "Hello") (define response (zmq-recv-string requester)) (printf "Client received ~s (#~s)\n" response request-number))
Server received: "Hello"Client received "World" (#0)Server received: "Hello"Client received "World" (#1)Server received: "Hello"Client received "World" (#2)
> (zmq-close requester)

1.2 Weather Reporting in ZeroMQ🔗

This example is adapted fromGetting the Message Out, which illustrates PUB-SUB communication.

Here’s the weather update server:

Here is the weather client:

> (define subscriber (zmq-socket 'sub #:connect "tcp://localhost:5556"))
> (define myzip (zip->string (random-zip)))
> (printf "Subscribing to ZIP code ~a only\n" myzip)
Subscribing to ZIP code 10001 only
> (zmq-subscribe subscriber myzip)
Client got temperature update #0: 40Client got temperature update #1: 53Client got temperature update #2: 130Client got temperature update #3: 22Client got temperature update #4: -77Client got temperature update #5: -4Client got temperature update #6: 85Client got temperature update #7: -2Client got temperature update #8: 100Client got temperature update #9: 96
> (printf "Average temperature for ZIP code ~s was ~s\n" myzip (~r (/ total-temp 10)))
Average temperature for ZIP code "10001" was "44.3"
> (zmq-close subscriber)

1.3 Divide and Conquer in ZeroMQ🔗

This example is adapted fromDivide and Conquer, which illustrates PUSH-PULL communication.

Here’s the ventilator:

; Task ventilator
; Binds PUSH socket to tcp://localhost:5557
; Sends batch of tasks to workers via that socket
> (define (ventilator go-sema) (define sender (zmq-socket 'push #:bind "tcp://*:5557")) (define sink (zmq-socket 'push #:connect "tcp://localhost:5558")) (semaphore-wait go-sema) (zmq-send sink "0") ; message 0 signals start of batch (define total-msec (for/fold ([total 0]) ([task-number (in-range 100)]) (define workload (add1 (random 100))) (zmq-send sender (format "~s" workload)) (+ total workload))) (printf "Total expected cost: ~s msec\n" total-msec) (zmq-close sender) (zmq-close sink))

Here are the workers:

; Task worker
; Connects PULL socket to tcp://localhost:5557
; Collects workloads from ventilator via that socket
; Connects PUSH socket to tcp://localhost:5558
; Sends results to sink via that socket

Here is the sink:

; Task sink
; Binds PULL socket to tcp://localhost:5558
; Collects results from workers via that socket

Now we create a sink thread, a ventilator thread, and 10 worker threads. We give them a little time to connect to each other, then we start the task ventilator and wait for the sink to collect the results.

Total expected cost: 5291 mseccpu time: 292 real time: 623 gc time: 0

Note that to achieve the desired parallel speedup here, it’s important to give all of the worker threads time to connect their receiver sockets—the (sleep 1) is a blunt way of doing this. Otherwise, the first thread to connect might end up doing all of the work—an example of the “slow joiner” problem (see the end ofDivide and Conquer for more details).

2 ZeroMQ API🔗

Returns #t if the ZeroMQ library (libzmq) was loaded successfully,#f otherwise. If the result is #f, callingzmq-socket will raise an exception. See ZeroMQ Requirements.

Added in version 1.1 of package zeromq-r-lib.

Returns the version of the ZeroMQ library (libzmq) if it was loaded successfully, #f otherwise. The version is represented by a list of three integers—for example, '(4 3 2).

Added in version 1.1 of package zeromq-r-lib.

2.1 Managing ZeroMQ Sockets🔗

Creates a new ZeroMQ socket of the given socket type and initializes it with identity, subscriptions,bind-endpoints, and connect-endpoints (in that order).

See the zmq_socket documentation for brief descriptions of the different types of sockets, and see the0MQ Guide for more detailed explanations.

A ZeroMQ socket acts as a synchronizable event(evt?) that is ready whenzmq-recv-message would receive a message without blocking; the synchronization result is the received message (zmq-message?). If the socket is closed, it is never ready for synchronization; use zmq-closed-evt to detect closed sockets.

Unlike libzmq, zmq-socket creates sockets with a short default “linger” period (ZMQ_LINGER), to avoid blocking the Racket VM when the underlying context is shut down. The linger period can be changed with zmq-set-option.

Returns #t if v is a ZeroMQ socket, #f otherwise.

Close the socket. Further operations on the socket will raise an error, except that zmq-close may be called on an already-closed socket.

Returns #t if the socket is closed, #f otherwise.

Returns a synchronizable event(evt?) that is ready for synchronization when (zmq-closed? s) would return #t. The synchronization result is the event itself.

List the endpoints the socket is bound or connected to (whenmode is 'bind or 'connect, respectively).

Gets or sets a socket option; see the API documentation forzmq_getsockopt andzmq_setsockopt, respectively. An option’s symbol is obtained from the name of the corresponding C constant by removing the ZMQ_ prefix and converting it to lower-case. For example, ZMQ_IPV6 becomes 'ipv6 andZMQ_LAST_ENDPOINT becomes 'last_endpoint. Not all options are supported. See also zmq-list-options.

Lists the options that this library supports forzmq-get-option or zmq-set-option whenmode is 'get or 'set, respectively.

Connect or bind the socket s to the given endpoint(s).

See the transport documentation pages (tcp,pgm, ipc,inproc, vmci,udp) for more information about transports and their endpoint notations.

If endpoint refers to a filesystem path or network address, access is checked against (current-security-guard). This library cannot parse and check all endpoint formats supported bylibzmq; if endpoint is not in a supported format, an exception is raised with the message “invalid endpoint or unsupported endpoint format.” The parsing and access control check can be skipped by using zmq-unsafe-connect or zmq-unsafe-bindinstead.

Disconnect or unbind the socket s from the given endpoint(s).

Note that in some cases endpoint must be more specific than the argument to zmq-bind or zmq-connect. For example, see the section labeled “Unbinding wild-card address from a socket” inzmq_tcp.

Adds or removes topic from a SUB ('sub) socket’s subscription list. A SUB socket starts out with no subscriptions, and thus receives no messages.

A topic matches a message if topic is a prefix of the message. The empty topic accepts all messages.

2.2 Sending and Receiving ZeroMQ Messages🔗

A ZeroMQ message consists of one or more frames(represented by byte strings). The procedures in this library support sending and receiving only complete messages (as opposed to the frame-at-a-time operations in the libzmq C library).

Returns #t if v is a ZeroMQ message value, #fotherwise.

Returns a ZeroMQ message value consisting of the given frames. Strings are automatically coerced to bytestrings using string->bytes/utf-8, and if a single string or bytestring is given, it is converted to a singleton list.

When used a match pattern, the frames subpattern is always matched against a list of bytestrings.

Examples:

> (define msg (zmq-message "hello world"))
> (match msg [(zmq-message frames) frames])
'(#"hello world")

In libzmq version 4.3.2, the draft (unstable) API has additional operations on messages to support the draft socket types; for example, a message used with a CLIENT or SERVER socket has a routing-idfield. Support will be added to zmq-message when the corresponding draft APIs become stable.

Added in version 1.1 of package zeromq-r-lib.

Sends the message msg on socket s.

Added in version 1.1 of package zeromq-r-lib.

Receives a message from socket s.

Added in version 1.1 of package zeromq-r-lib.

Sends a message on socket s. The message has as many frames as msg-frame arguments, with at least one frame required.

Sends the message msg on socket s, wheremsg consists of a non-empty list of frames.

Receives a one-frame message from the socket s and returns the single frame as a byte string or character string, respectively.

If a multi-frame message is received from s, an error is raised. (The message is still consumed.)

Receives a message from the socket s. The message is represented as a list of byte strings, one for each frame.

Runs a proxy connecting sock1 and sock2; a loop reads a message from either socket and sends it to the other. For each message received, the capture procedure is called on the receiving socket and the received message, and then the message is forwarded to the other socket.

This procedure returns only when the proxy is finished, either because one of the sockets is closed—in which case (void) is returned—or because other-evt became ready for synchronization—in which case other-evt’s synchronization result is returned. The procedure might also raise an exception due to a failed send or receive or if capture or other-evtraise an exception.

Added in version 1.1 of package zeromq-r-lib.

3 ZeroMQ Unsafe Functions🔗

The functions provided by this module are unsafe.

Like zmq-connect and zmq-bind, but do not attempt to parse the endpoint arguments and perform security guard checks.

These functions are unsafe, not in the sense that misuse is likely to cause memory corruption, but in the sense that they do not respect the current security guard.

Returns two values: the-ctx and keepalive. The first value,the-ctx, is a pointer to the ZeroMQ context (zmq_ctx) used to create all sockets managed by the current instance of this library. Note that if multiple namespaces each instantiate this library, each instance has a different context.

The context is automatically destroyed when there are no references to it visible to the Racket GC; there is a reference in every socket created with it. In addition, the keepalive value holds a reference to the context, so as long as keepalive is visible to the Racket GC, the context will not be destroyed. (Currently keepalive is the same asthe-ctx, but future versions of this library may implement context finalization differently.)

Added in version 1.2 of package zeromq-r-lib.

4 ZeroMQ Requirements🔗

This library requires the libzmq foreign library to be installed in either the operating system’s default library search path or in Racket’s extended library search path (see get-lib-search-dirs).

On Linux, libzmq.so.5 is required. On Debian-based systems, it is available from the libzmq5 package. On RedHat-based systems, it is available from the zeromq package.

On Mac OS, libzmq.5.dylib is required.

On Windows, libzmq.dll is required. It is automatically installed via the zeromq-win32-{i386,x86_64} package.