zeroqm sockets

Share your advanced PureBasic knowledge/code with the community.
User avatar
idle
Always Here
Always Here
Posts: 5915
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

zeroqm sockets

Post by idle »

I'd completely forgotten about this library, which on the face of it looks really good.
when they say sockets on steroids, I'm inclined to believe them.
ØMQ (zeromq)
The socket library that acts as a concurrency framework.
Carries messages across inproc, IPC, TCP, and multicast.
Connect N-to-N via fanout, pubsub, pipeline, request-reply.
Asynch I/O for scalable multicore message-passing apps.
I've included builds for windows x86 and linux x64
there are windows dll's available off the zeroqm.org
loads of examples and online guide

http://zguide.zeromq.org/page:all

ØMQ download

Example of client

Code: Select all

IncludeFile "zmq.pbi"

Procedure main()
    Debug "Connecting to hello world server..";
    context = zmq_ctx_new ();
    requester = zmq_socket (context, #ZMQ_REQ);
    zmq_connect (requester, @"tcp://localhost:5555");
  
    For request_nbr = 0 To 10 
        buffer.s = Space(10);
        Debug "Sending Hello " + Str(request_nbr)
        zmq_send (requester, @"Hello", 5, 0);
        zmq_recv (requester, @buffer, 10, 0);   blocks untill recieved 
        Debug "Received  " + buffer 
    Next 
    zmq_close (requester);
    zmq_ctx_destroy (context);
 EndProcedure 
  
 If Init_zmq(zmqlibpath)
   main() 
EndIf    
Example of multi threaded server

Code: Select all

IncludeFile "zmq.pbi"

Procedure worker(context) 
   Protected reciver,buf.s 
   receiver = zmq_socket (context, #ZMQ_REP);
   zmq_connect (receiver, @"inproc://workers");

    While 1  
       buf.s = Space(10) 
       zmq_recv(receiver,@buf,10,0)
       Delay(1);
       zmq_send(receiver,@"World",5,0)
    Wend  
    zmq_close (receiver);
       
EndProcedure    

Procedure main() 
   
   context = zmq_ctx_new ();
   clients = zmq_socket (context, #ZMQ_ROUTER);
   zmq_bind (clients, @"tcp://*:5555");
   
   workers = zmq_socket (context, #ZMQ_DEALER);
    zmq_bind (workers, @"inproc://workers");

    For thread_nbr = 0 To 5 
        tworker = CreateThread(@worker(),context) 
    Next    
    
    zmq_proxy (clients, workers, #Null);

    ;//  example never gets here, but clean up anyhow
    zmq_close (clients);
    zmq_close (workers);
    zmq_ctx_destroy (context);
    
 EndProcedure 

If Init_zmq(zmqlibpath)
   main() 
EndIf    

Windows 11, Manjaro, Raspberry Pi OS
Image
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: zeroqm sockets

Post by sec »

Thanks, looks great.

Have you build for Win x64?

@idle: On Win 32bit

i got 4K memory leak on server process (it is increase 4k+ ...) after sometimes run client, do you know why?

the server:

Code: Select all

IncludeFile "zmq.pbi"


Procedure worker(context) 
   Protected reciver,buf.s 
   receiver = zmq_socket (context, #ZMQ_REP);
   zmq_connect (receiver, @"inproc://workers");

    While 1  
       buf.s = Space(10) 
       zmq_recv(receiver,@buf,10,0)

       Debug buf
       If buf = "refresh"
         buf = "a|b|c|d"
       Else
         buf = "unknow"
       EndIf
       
       zmq_send(receiver,@buf,7+1,0)
       
    Wend  
    zmq_close (receiver);
       
EndProcedure    

Procedure main() 
   
   context = zmq_ctx_new ();
   
   ;//  Socket To talk To clients
    clients = zmq_socket (context, #ZMQ_ROUTER);
    zmq_bind (clients, @"tcp://*:5555");

    ;//  Socket To talk To workers
    workers = zmq_socket (context, #ZMQ_DEALER);
    zmq_bind (workers, @"inproc://workers");

    ;//  Launch pool of worker threads
    For thread_nbr = 0 To 5 
        tworker = CreateThread(@worker(),context) 
    Next    
     ;//  Connect work threads To client threads via a queue proxy
    zmq_proxy (clients, workers, #Null);

    ;//  We never get here, but clean up anyhow
    zmq_close (clients);
    zmq_close (workers);
    zmq_ctx_destroy (context);
    
 EndProcedure 

If Init_zmq(zmqlibpath)
   main() 
EndIf    
the client:

Code: Select all

IncludeFile "zmq.pbi"

Procedure main()
    Debug "Connecting to hello world server..";
    context = zmq_ctx_new ();
    requester = zmq_socket (context, #ZMQ_REQ);
    zmq_connect (requester, @"tcp://localhost:5555");
  
    For request_nbr = 0 To 10 
        buffer.s = Space(10);
        Debug "Sending Hello " + Str(request_nbr)
        zmq_send (requester, @"refresh", 7+1, 0);
        zmq_recv (requester, @buffer, 10, 0);   blocks untill recieved 
        Debug "Received  " + buffer 
    Next 
    zmq_close (requester);
    zmq_ctx_destroy (context);
 EndProcedure 
  
 If Init_zmq(zmqlibpath)
   main() 
EndIf    
 
User avatar
idle
Always Here
Always Here
Posts: 5915
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: zeroqm sockets

Post by idle »

I can't build for the libs for windows, I just downloaded the binaries and chose one
there's a whole bunch of windows versions for some reason.

As for the leak i'm not sure
but it might be the length of the message since it doesn't include a null, so where you have

zmq_send(receiver,@buf,7+1,0)
change it to

zmq_send(receiver,@buf,7,0)

also the examples aren't complete. they're just straight ports of the examples in the doc guide
Windows 11, Manjaro, Raspberry Pi OS
Image
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: zeroqm sockets

Post by sec »

idle wrote:I can't build for the libs for windows, I just downloaded the binaries and chose one
there's a whole bunch of windows versions for some reason.

As for the leak i'm not sure
but it might be the length of the message since it doesn't include a null, so where you have

zmq_send(receiver,@buf,7+1,0)
change it to

zmq_send(receiver,@buf,7,0)

also the examples aren't complete. they're just straight ports of the examples in the doc guide
Thanks, i remove that +1, this simple server example is still leak 4k after run client some times
User avatar
idle
Always Here
Always Here
Posts: 5915
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: zeroqm sockets

Post by idle »

the server isn't leaking from what I can see on xp
but the client might be the buffer string wasn't getting cleared

Code: Select all

IncludeFile "zmq.pbi"

Procedure main()
    Debug "Connecting to hello world server..";
    context = zmq_ctx_new ();
    requester = zmq_socket (context, #ZMQ_REQ);
    zmq_connect (requester, @"tcp://localhost:5555");
  
    For request_nbr = 0 To 10 
        buffer.s = Space(10);
        Debug "Sending Hello " + Str(request_nbr)
        zmq_send (requester, @"Hello", 5, 0);
        zmq_recv (requester, @buffer, 10, 0);   blocks untill recieved 
        Debug "Received  " + buffer 
        buffer=""
    Next 
    zmq_close (requester);
    zmq_ctx_destroy (context);
 EndProcedure 
  
 If Init_zmq(zmqlibpath)
    For a = 0 To 1000 
        main()  
    Next    
EndIf    
Windows 11, Manjaro, Raspberry Pi OS
Image
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: zeroqm sockets

Post by sec »

@idle: have you example about using zmq_getsockopt() ? or how receive large data over zmq_recv.

Thanks.
User avatar
idle
Always Here
Always Here
Posts: 5915
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: zeroqm sockets

Post by idle »

No, I haven't looked into it further yet.
Take a look in the guide and search for examples with ZMQ_More for sending large files
when you use zmq_send / recv the data is copied into memory so you would need to fragment large files
but you should be able to steam using zmq_zerocopy and using zmq_more flag
Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply