CL-RemiZMQ
CL-RemiZMQ is a library for Common Lisp that implements bindings for
ZeroMQ. This includes ZeroMQ sockets, messages, timers,
atomics, and proxies. It has been primarily developed on SBCL, but should also
work in ClozureCL or most other Lisp implementations that support threads.
CL-RemiZMQ is entirely written and maintained by one person, Remilia Scarlet! If you want to support her and CL-RemiZMQ, you can buy her a coffee on Ko-Fi, or support her through Liberapay. Support is greatly appreciated for this volunteer effort ^_^
How do I get set up?
This has been tested with libzmq v5.2.5, but any v4.x and v5.x should work. v3.x may work as well.
There are five main dependencies:
All of these except for CL-SDM may be installed via Quicklisp. The CL-SDM library is not available in Quicklisp and must be installed manually by placing it somewhere where ASDF can locate it.
Once you have the dependencies, run this in your REPL:
(asdf:load-system :cl-remizmq)
Usage
There are two APIs, each with their own package:
- The Low-level API (
:zmq-low): Low-level CFFI-based API that is a 1:1 mapping between libzmq and Common Lisp. - The High Level API (
:zmq): A high-level CLOS-based API. This will automatically handle freeing of memory, and feels much more Common Lisp-y.
In most cases you will want to use the High Level API, though you can (with careful use) intermix the two when needed.
Here is an example of how to use the High Level API to implement the Hello World client example from the official ZeroMQ guide:
(let* ((ctx (zmq:make-zmq-context))
(socket (zmq:make-zmq-socket ctx :req)))
(zmq:zmq-socket-connect socket "tcp://localhost:5555")
(dotimes (nbr 10)
(zmq:zmq-socket-send socket "Hello")
(print (zmq:bytes->string (zmq-socket-receive socket)))))
Or, even shorter:
(zmq:with-context-and-socket (ctx socket :connect-to "tcp://localhost:5555")
(dotimes (nbr 10)
(print (zmq:send-and-receive socket "Hello" :as-string t))))
Additional examples are available in the examples/ directory.
Important Note
When using the REPL, of you have a socket that's waiting to receive input, and you use Ctrl-C, that socket may not get GC'd properly. This is due to how the Lisp runtime handles interrupts. You'll need to workaround this by setting a timeout, setting it not to block, sending a message manually in the REPL so it stops blocking, or just letting the small amount of memory leak.
This does not apply when building executable binaries.
Development
Style info
I use a slightly unorthodox style for my code. Aside from these differences, please use normal Lisp formatting.
- Keep lines 118 characters or shorter. Obviously sometimes you can't, but please try. Use 115 characters for Markdown files, though.
- I mark types using the form
T/..... For example,T/SOME-NEAT-TYPE. For predicates on these, useSOME-NEAT-TYPE-P. - No tabs. Only spaces.
How do I contribute?
- Go to https://fossil.cyberia9.org/cl-remizmq/ and clone the Fossil repository.
- Create a new branch for your feature.
- Push locally to the new branch.
- Create a bundle with Fossil that contains your changes.
- Get in contact with Remilia via email, Fediverse, or open a ticket.
Contributors
- Remilia Scarlet - creator and maintainer
- Homepage: https://remilia.sdf.org/
- Fediverse: @remilia@social.cyberia9.org
- Email: zremiliaz@postzeoz.jpz My real address does not contain Z's
Links and Licenses
CL-RemiZMQ is under the GNU Affero General Public License version 3.
