Jump to content


Photo

zeromq class


  • Please log in to reply
2 replies to this topic

#1 tinku99

tinku99
  • Members
  • 560 posts

Posted 09 April 2012 - 02:29 AM

the tcp class, example from the german forum inspired me to take another crack at zeromq in ahk.

zeromq is a socket library that:
[*]Carries messages across inproc, IPC, TCP, and multicast.
[*]Connect N-to-N via fanout, pubsub, pipeline, request-reply.
[*]supports interaction between 30+ languages including C, C++, Java, .NET, Python, and now autohotkey!

I got the rep/req example from the zguide working: <!-- m -->http://zguide.zeromq.org<!-- m -->
hwserver.ahk
z := new zmq()
context := z.zmq_init(1)
responder := z.zmq_socket(context, z.ZMQ_REP)
                                           
VarSetCapacity(request, 16, 0)
VarSetCapacity(reply, 16, 0)                      

hr := z.zmq_bind(responder, "tcp://*:5555")
assert(hr)                                          
loop {
hr := z.zmq_msg_init(&request)
assert(hr)                
hr := z.zmq_recv(responder, &request, z.ZMQ_NOBLOCK)
if (hr != 0){
sleep, 200
continue 
}       
size := z.zmq_msg_size(&request)
msgp := z.zmq_msg_data(&request)        
msg := StrGet(msgp, 5, "utf-8")       
hr := z.zmq_msg_close(&request)
ToolTip, % "server: Received: " msg " of size: " size, 0, 0               
hr := z.zmq_msg_init_size(&reply, 5)
assert(hr)                         
msgp := z.zmq_msg_data(&reply)
strput("World", msgp, 5, "utf-8")
tooltip % "Sending world ", 0, 0   
hr := z.zmq_send(responder, &reply, 0)
assert(hr)                            
hr := z.zmq_msg_close(&reply)
assert(hr)                   
}         
return                                       
!r::reload                                   
!q::
hr := z.zmq_close(responder)
hr := z.zmq_term(context)
exitapp                                  
assert(hr){                       
if ErrorLevel{
listlines 
msgbox % ErrorLevel
}
if hr                             
msgbox % "error: " hr             
}                
return

#include lib\zmq.ahk
hwclient.ahk:
z := new zmq()
msgbox % z.__handle "`n" z.ZMQ_REQ
context := z.zmq_init(1)
tooltip, % "Connecting to hello world server…"   
requester := z.zmq_socket(context, z.ZMQ_REQ)
     
hr := z.zmq_connect(requester, "tcp://localhost:5555")
assert(hr)                                          
VarSetCapacity(request, 16, 0)                      
hr := z.zmq_msg_init_size(&request, 5)
assert(hr)                         
msgp := z.zmq_msg_data(&request)
strput("Hello", msgp, 5, "utf-8")
tooltip % "Sending Hello "   
hr := z.zmq_send(requester, &request, 0)
assert(hr)                            
hr := z.zmq_msg_close(&request)
assert(hr)                   
VarSetCapacity(reply, 16, 0)
hr := z.zmq_msg_init(&reply)
assert(hr)                
hr := z.zmq_recv(requester, &reply, 0)
assert(hr)                          
size := z.zmq_msg_size(&reply)
msgp := z.zmq_msg_data(&reply)        
msg := StrGet(msgp, 5, "utf-8")       
hr := z.zmq_msg_close(&reply)
hr := z.zmq_close(requester)
hr := z.zmq_term(context)                                      
tooltip, % "Received " msg " of size: " size                
listvars                                     
msgbox                                       
return                                       
!r::reload                                   
!q::exitapp                                  
assert(hr){                       
if ErrorLevel{
listlines
msgbox % ErrorLevel
}
if hr                             
msgbox % "error: " hr             
}                
return

#include lib\zmq.ahk
lib: zmq.ahk
class zmq {
static ZMQ_PAIR := 0 
static ZMQ_PUB := 1  
static ZMQ_SUB := 2  
static ZMQ_REQ := 3  
static ZMQ_REP := 4  
static ZMQ_DEALER := 5
static ZMQ_ROUTER := 6
static ZMQ_PULL := 7 
static ZMQ_PUSH := 8 
static ZMQ_XPUB := 9 
static ZMQ_XSUB := 10
static ZMQ_HWM := 1
static ZMQ_SWAP := 3
static ZMQ_AFFINITY := 4
static ZMQ_IDENTITY := 5
static ZMQ_SUBSCRIBE := 6
static ZMQ_UNSUBSCRIBE := 7
static ZMQ_RATE := 8
static ZMQ_RECOVERY_IVL := 9
static ZMQ_MCAST_LOOP := 10
static ZMQ_SNDBUF := 11
static ZMQ_RCVBUF := 12
static ZMQ_RCVMORE := 13
static ZMQ_FD := 14
static ZMQ_EVENTS := 15
static ZMQ_TYPE := 16
static ZMQ_LINGER := 17
static ZMQ_RECONNECT_IVL := 18
static ZMQ_BACKLOG := 19
static ZMQ_RECOVERY_IVL_MSEC := 20
static ZMQ_RECONNECT_IVL_MAX := 21
static ZMQ_NOBLOCK := 1
static ZMQ_SNDMORE := 2
static ZMQ_POLLIN := 1
static ZMQ_POLLOUT := 2
static ZMQ_POLLERR := 4
static ZMQ_STREAMER := 1
static ZMQ_FORWARDER := 2
static ZMQ_QUEUE := 3
      

   __New(){
libzmq := dllcall("LoadLibrary", "str", "libzmq.dll")
if !libzmq{                                     
throw "error loading " file
} 
this.__handle := libzmq
}
__call(func, args*) {
        types := this[func].arg_types
            loop % types.maxindex() 
                args.insert((A_Index<<1)-1, types[A_Index])
            args.insert("cdecl " this[func].returntype)
            ; msgbox % tostring(args)
        return DllCall("libzmq\" func, args*)      
    }                                  
static zmq_msg_init := {arg_types: ["Ptr"], returntype : "int"}
static zmq_msg_init_size := {arg_types: ["Ptr", "uint"], returntype : "int"} 
static zmq_msg_init_data := {arg_types: ["Ptr", "Ptr", "uint"
, "Ptr", "Ptr"], returntype : "int"}
static zmq_msg_close := {arg_types: ["Ptr"], returntype : "int"}
static zmq_msg_move := {arg_types: ["Ptr", "Ptr"], returntype : "int"}
static zmq_msg_copy := {arg_types: ["Ptr", "Ptr"], returntype : "int"}
static zmq_msg_data := {arg_types: ["Ptr"], returntype : "Ptr"}
static zmq_msg_size := {arg_types: ["Ptr"], returntype : "uint"}
                           
static zmq_init := {arg_types: ["int"], returntype: "Ptr"} 
static zmq_term := {arg_types: ["Ptr"], returntype: "int"}    
static zmq_socket := {arg_types: ["Ptr", "int"], returntype: "Ptr"}                     
static zmq_close := {arg_types: ["Ptr"], returntype: "int"}                                        
static zmq_setsockopt := {arg_types: ["Ptr", "int"
,  "Ptr", "Ptr"], returntype: "int"}                         
static zmq_getsockopt := {arg_types: ["Ptr", "int"
, "Ptr", "Ptr"], returntype: "int"} 
static zmq_bind := {arg_types: ["Ptr",  "astr"], returntype: "int"}                       
static zmq_connect := {arg_types: ["Ptr", "astr"], returntype: "int"}                    
static zmq_send := {arg_types: ["Ptr", "Ptr", "int"], returntype: "int"}              
static zmq_recv := {arg_types: ["Ptr", "Ptr", "int"], returntype: "int"}              
static zmq_poll := {arg_types: ["Ptr", "int", "long"], returntype: "int"}
static zmq_device := {arg_types: ["int", "Ptr", "Ptr"], returntype: "int"}
static zmq_errno := {arg_types: [], returntype: "int"}
static zmq_strerror := {arg_types: ["int"], returntype: "astr"}
}
git repo
Please send me a pull request if you get any other zguide examples working.

#2 tinku99

tinku99
  • Members
  • 560 posts

Posted 18 April 2012 - 11:28 PM

a simple wrapper to send and receive objects using json.
requires: lib_json


#3 tinku99

tinku99
  • Members
  • 560 posts

Posted 29 April 2012 - 05:35 PM

updated wrapper to use json-js.
for serializing ahk objects to json, use: ahkvec2json()