Skip to content

Latest commit

 

History

23 Commits

Folders and files

Repository files navigation

FreeBasicZMQ

ZMQ Wrapper for FreeBasic Programming Language.

GitHub FreeBasic Dependency

Environment

  • Windows 7 above (recommend)
  • FreeBasic 1.10.1 above (recommend)
  • ZeroMQ / libzmq 4.3.6 (binding targets this API)

How to Build

Building requires FreeBasic Compiler (tested under Windows 10/11).

fbc Example/PubServer.bas -target win64

Running Examples

  1. Set the process working directory to the package root that contains Core/, Example/, and Library/ (for example FreeBasicZMQ/FreeBasicZMQ).
  2. Examples load Library/x64/libzmq.dll or Library/x86/libzmq.dll (and libsodium.dll when present) via Chdir into that folder.
  3. Prefer fbc64.exe for x64 binaries so the x64 DLL is used.

Pub / Sub start order

  1. Start Pub first (PubServer, WeatherPubServer, …).
  2. Wait for the bind message (publishers also pause ~200 ms for the slow-joiner case).
  3. Start Sub (SubClient, WeatherSubClient, …).
  4. Subscribers call ZMQ_SUBSCRIBE before Connect.

Capability Probe (zmq_has)

Run Example/Has.bas (or Example/Module/Has.bas) after loading the DLL:

Capability string Meaning
ipc IPC transport
curve CURVE security (zmq_curve_*)
draft Draft API build
pgm / norm / tipc / … Optional transports (if compiled in)

The bundled Windows libzmq.dll is CURVE-enabled and should report curve=1. The Curve / CurveKeypair demos use the bundled CURVE support; zmq_has("curve") remains a runtime check for deployments that replace the DLL. DLL symbols are resolved once on open (Core/Symbols.bi).

Example (PUB / SUB)

Publisher Server

fbc Example/PubServer.bas -target win64
#Include "Core/Enums.bi"
#Include "Core/ZeroMQWrapper.bi"

Dim lpszLibZmqDll As String = "libzmq.dll"

Function RndRange(Byval first As Double, Byval last As Double) As Double
    Function = Rnd * (last - first) + first
End Function

Const lpszServerAddr As String = "tcp://*:1689"

Dim ZmqContextRec As LibZmqContext
Dim ZmqSocketRec As LibZmqSocket
Dim ZmqRuntimeRec As LibZmqRuntime

If LibZMQWrapper.DllOpen(lpszLibZmqDll) Then
    Dim Context As Any Ptr = ZmqContextRec.NewCtx()
    Dim Socket As Any Ptr = ZmqSocketRec.Socket(Context, ZMQ_PUB)
    Dim Rc As Long = ZmqSocketRec.Bind(Socket, lpszServerAddr)

    If Rc <> 0 Then
        Print("Bind failed: " & *ZmqRuntimeRec.Strerror(ZmqRuntimeRec.Errno()))
    Else
        Print("Bind an IP address: " & lpszServerAddr)
        Sleep(200)
        Randomize

        While 1
            Dim lpszTopic As String = "quotes"
            Dim lpszSendMessage As String = "Bid:" & Str(CInt(RndRange(1000, 9000))) & ",Ask:" & Str(CInt(RndRange(1000, 9000)))

            If ZmqSocketRec.Send(Socket, StrPtr(lpszTopic), Len(lpszTopic), ZMQ_SNDMORE) = -1 Then
                Print("Send topic failed: " & *ZmqRuntimeRec.Strerror(ZmqRuntimeRec.Errno()))
            ElseIf ZmqSocketRec.Send(Socket, StrPtr(lpszSendMessage), Len(lpszSendMessage), 0) = -1 Then
                Print("Send message failed: " & *ZmqRuntimeRec.Strerror(ZmqRuntimeRec.Errno()))
            Else
                Print("Published: " & lpszSendMessage)
            End If

            Sleep(100)
        Wend
    End If

    ZmqSocketRec.Close(Socket)
    ZmqContextRec.Shutdown(Context)
    LibZMQWrapper.DllClose()
End If

Subscribe Client

fbc Example/SubClient.bas -target win64
#Include "Core/Enums.bi"
#Include "Core/ZeroMQWrapper.bi"

Dim lpszLibZmqDll As String = "libzmq.dll"
Const lpszServerAddr As String = "tcp://localhost:1689"

Dim ZmqContextRec As LibZmqContext
Dim ZmqSocketRec As LibZmqSocket
Dim ZmqRuntimeRec As LibZmqRuntime

If LibZMQWrapper.DllOpen(lpszLibZmqDll) Then
    Dim Context As Any Ptr = ZmqContextRec.NewCtx()
    Dim Socket As Any Ptr = ZmqSocketRec.Socket(Context, ZMQ_SUB)
    Dim lpszSubscribe As String = "quotes"
    Dim Rc As Long

    ZmqSocketRec.Setsockopt(Socket, ZMQ_SUBSCRIBE, StrPtr(lpszSubscribe), Len(lpszSubscribe))
    Rc = ZmqSocketRec.Connect(Socket, lpszServerAddr)

    If Rc <> 0 Then
        Print("Connect failed: " & *ZmqRuntimeRec.Strerror(ZmqRuntimeRec.Errno()))
    Else
        Print("Connected: " & lpszServerAddr & " (subscribe=" & lpszSubscribe & ")")

        While 1
            Dim lpszTopicBuffer As ZString * 256
            Dim lpszRecvBuffer As ZString * 256
            Dim TopicBytes As Long
            Dim MessageBytes As Long

            TopicBytes = ZmqSocketRec.Recv(Socket, @lpszTopicBuffer, SizeOf(lpszTopicBuffer), 0)

            If TopicBytes <> -1 Then
                MessageBytes = ZmqSocketRec.Recv(Socket, @lpszRecvBuffer, SizeOf(lpszRecvBuffer), 0)
                If MessageBytes <> -1 Then
                    Print(Left(lpszRecvBuffer, MessageBytes))
                End If
            End If
        Wend
    End If

    ZmqSocketRec.Close(Socket)
    ZmqContextRec.Shutdown(Context)
    LibZMQWrapper.DllClose()
End If

Examples

Example Pattern Notes
Zmq / Has Version / zmq_has / sockopt Smoke / capability
PubServer + SubClient PUB/SUB multipart Port 1689, topic quotes
Weather/* + Module/Weather* PUB/SUB weather Port 1692, simulated updates (no HTTP API)
ReqClient + RepServer REQ/REP
Plain PLAIN + ZAP Port 1720, user admin / secret
Curve / CurveKeypair CURVE Needs zmq_has("curve")=1
Poll / Proxy / Monitor Poll, steerable proxy, monitor
Z85 Z85 encode/decode
Msg / Thread / Stopwatch Msg API / helpers

Each major sample has a procedural copy under Example/ and an OOP twin under Example/Module/.

License

Copyright (c) 2017-2026 Ji-Feng Tsai.
Code released under the MIT license.

TODO

  • Atomic counters / timers

Donation

If this application help you reduce time to coding, you can give me a cup of coffee :)

paypal

Paypal Me

Releases

Packages

Used by

Contributors

Languages