ZMQ Wrapper for PureBasic Programming Language.
- Windows 10 above (recommend)
- PureBasic 6.0 above (recommend)
- ZeroMQ (libzmq 4.3.6 API constants; runtime version comes from your DLL)
Building requires PureBasic Compiler and test under Windows 11.
Module features require PureBasic 5.20 and above.
Place libzmq.dll under PureBasicZMQ/Library/x64 or PureBasicZMQ/Library/x86 (examples resolve the path from the processor).
libzmq conventions apply:
- Most calls return
0on success and-1on failure (for exampleBind,Connect,Setsockopt,Close). Send/Recvreturn the number of bytes on success, or-1on failure.Socket/CtxNewreturn a non-zero handle on success, or0/nullon failure.- After a failed call, use
ZmqErrno()/ZmqRuntime::Errno()andZmqStrerror()/ZmqRuntime::Strerror()for the reason. - Do not treat every
0as failure:0is success for many APIs.
Example:
Define Rc.i = ZmqSocket::Bind(Socket, lpszServerAddr)
If Rc <> 0
PrintN("Bind failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
EndIf
Publisher Server (ZMQ_PUB is send-only — do not call Recv on it)
EnableExplicit
IncludeFile "../../Core/Enums.pbi"
IncludeFile "../../Core/ZeroMQWrapper.pbi"
UseModule ZeroMQWrapper
Global lpszLibZmqDll.s = "libzmq.dll"
Global lpszServerAddr.s = "tcp://*:1689"
If DllOpen(lpszLibZmqDll)
OpenConsole()
Define Context.i = ZmqContext::New()
Define Socket.i = ZmqSocket::Socket(Context, #ZMQ_PUB)
Define Rc.i = ZmqSocket::Bind(Socket, lpszServerAddr)
If Rc <> 0
PrintN("Bind failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
Else
PrintN("Bind an IP address: " + lpszServerAddr)
Delay(200) ; slow joiner: give subscribers time to connect
While 1
Define lpszTopic.s = "quotes"
Define lpszMessage.s = "Bid:" + Random(9000, 1000) + ",Ask:" + Random(9000, 1000)
If ZmqSocket::Send(Socket, lpszTopic, Len(lpszTopic), #ZMQ_SNDMORE) = -1
PrintN("Send topic failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
ElseIf ZmqSocket::Send(Socket, lpszMessage, Len(lpszMessage), 0) = -1
PrintN("Send message failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
Else
PrintN("Published: " + lpszMessage)
EndIf
Delay(100)
Wend
EndIf
ZmqSocket::Close(Socket)
ZmqContext::Shutdown(Context)
CloseConsole()
DllClose()
EndIf
Subscribe Client
EnableExplicit
IncludeFile "../../Core/Enums.pbi"
IncludeFile "../../Core/ZeroMQWrapper.pbi"
UseModule ZeroMQWrapper
Global lpszLibZmqDll.s = "libzmq.dll"
Global lpszServerAddr.s = "tcp://localhost:1689"
If DllOpen(lpszLibZmqDll)
OpenConsole()
Define Context.i = ZmqContext::New()
Define Socket.i = ZmqSocket::Socket(Context, #ZMQ_SUB)
Define lpszSubscribe.s = "quotes"
; Subscribe before connect to reduce missed early messages.
ZmqSocket::Setsockopt(Socket, #ZMQ_SUBSCRIBE, lpszSubscribe, Len(lpszSubscribe))
Define Rc.i = ZmqSocket::Connect(Socket, lpszServerAddr)
If Rc <> 0
PrintN("Connect failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
Else
While 1
Define *lpszTopicBuffer = AllocateMemory(256)
Define *lpszBuffer = AllocateMemory(256)
Define TopicBytes.i
Define MessageBytes.i
TopicBytes = ZmqSocket::Recv(Socket, *lpszTopicBuffer, MemorySize(*lpszTopicBuffer), 0)
If TopicBytes = -1
PrintN("Recv topic failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
Else
MessageBytes = ZmqSocket::Recv(Socket, *lpszBuffer, MemorySize(*lpszBuffer), 0)
If MessageBytes = -1
PrintN("Recv message failed: " + ZmqRuntime::Strerror(ZmqRuntime::Errno()))
Else
; Use Recv byte count — ZMQ payloads are not null-terminated.
PrintN(PeekS(*lpszBuffer, MessageBytes, #PB_UTF8))
EndIf
EndIf
FreeMemory(*lpszTopicBuffer)
FreeMemory(*lpszBuffer)
Wend
EndIf
ZmqSocket::Close(Socket)
ZmqContext::Shutdown(Context)
CloseConsole()
DllClose()
EndIf
| Pattern | Low-level | Module | Port |
|---|---|---|---|
| PUB / SUB | PubServer.pb, SubClient.pb |
Module/PubServer.pb, Module/SubClient.pb |
1689 |
| REQ / REP | ReqClient.pb, RepServer.pb |
Module/ReqClient.pb, Module/RepServer.pb |
1700 |
| PUSH / PULL | PushServer.pb, PullClient.pb |
Module/PushServer.pb, Module/PullClient.pb |
1701 |
| DEALER / ROUTER | DealerClient.pb, RouterServer.pb |
Module/DealerClient.pb, Module/RouterServer.pb |
1702 |
| PAIR | PairClient.pb, PairServer.pb |
Module/PairClient.pb, Module/PairServer.pb |
1703 |
| STREAM | StreamClient.pb, StreamServer.pb |
Module/StreamClient.pb, Module/StreamServer.pb |
1704 |
| Multipart helpers | Frames.pb |
Module/Frames.pb |
1705 |
| Monitor | Monitor.pb |
Module/Monitor.pb |
1700 (+ inproc) |
Also: Has, Poll, Proxy, Z85, Curve*, Plain, Msg, Thread, Stopwatch, Weather.
Multipart API (Core/Frames.pbi / ZmqFrames): SendFrames, SendStrings, RecvAllFrames, FramesFree, HasRcvMore, FrameToStr.
Copyright (c) 2017-2026 Ji-Feng Tsai.
Code released under the MIT license.
If this application help you reduce time to coding, you can give me a cup of coffee :)