' See ZMQHelpers.inc for s_send and s_recv consolidation ' A simple ØMQ Client that sends a query and recovers a response #COMPILE EXE "ZMQClient.exe" #INCLUDE "ZMQ.inc" $DEBUG_FILE = "ZMQ_Client_Debug.txt" GLOBAL hDbg AS LONG '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ SUB CopyMem( BYVAL pDS AS DWORD, BYVAL pSrc AS DWORD, BYVAL CopyLen AS DWORD ) ' MoveMemory BYVAL pDS, BYVAL pSrc, BYVAL CopyLen // Win API #REGISTER NONE ! cld ! mov esi, pSrc ! mov edi, pDS ! mov ecx, CopyLen ! shr ecx, 2 ! rep movsd ! mov ecx, CopyLen ! AND ecx, 3 ! rep movsb END SUB '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤' FUNCTION SendMessageZmq( sConnection AS STRING ) AS LONG LOCAL i, RetVal, MsgSz AS LONG LOCAL pCtx, pSoc AS DWORD LOCAL pData AS ASCIIZ PTR LOCAL pMsgIn, pMsgOut AS zmq_msg_t LOCAL sQuery, sResponse AS STRING LOCAL pzErr AS ASCIIZ PTR pCtx = zmq_init(1) ' Initialise 0MQ context - app_threads, io_threads, flags IF pCtx = 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_init: " + @pzErr FUNCTION = -1 EXIT FUNCTION END IF '============= DO ' device to jump out and still close socket and release ZMQ pSoc = zmq_socket( pCtx, %ZMQ_REQ ) ' ZMQ_REQ socket to send requests and receive replies IF pSoc = 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_socket: " + @pzErr FUNCTION = -2 EXIT DO END IF '============= RetVal = zmq_connect( pSoc, STRPTR(sConnection) ) ' PRINT #hDbg, "sConnection="+sConnection IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_connect: " + @pzErr FUNCTION = -3 EXIT DO END IF '============= '- Send a message sQuery = "SELECT * FROM mytable, END SERVER" ' PRINT #hDbg, "Query=" + sQuery RetVal = zmq_msg_init_size( VARPTR(pMsgOut), LEN(sQuery) ) ' Allocate a message IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_msg_init_size: " + @pzErr FUNCTION = -4 EXIT DO END IF CopyMem( zmq_msg_data(VARPTR(pMsgOut)), STRPTR(sQuery), LEN(sQuery) ) ' Copy message to ZMQ RetVal = zmq_send( pSoc, VARPTR(pMsgOut), 0) ' Send Message IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error sending message: " + @pzErr FUNCTION = -5 EXIT DO END IF '============= '- Recover response RetVal = zmq_msg_init(VARPTR(pMsgIn)) ' Init must be called before zmq_recv IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_msg_init: " + @pzErr FUNCTION = -6 EXIT DO END IF RetVal = zmq_recv( pSoc, VARPTR(pMsgIn), 0 ) ' Receive a message, blocks until one is available IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_recv: " + @pzErr FUNCTION = -7 EXIT DO END IF MsgSz = zmq_msg_size(VARPTR(pMsgIn)) ' Check Message for content IF MsgSz = 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "message size=0" FUNCTION = -8 EXIT DO END IF pData = zmq_msg_data(VARPTR(pMsgIn)) ' PRINT #hDbg, "Response=" + @pData IF pData = 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "message data pointer error" FUNCTION = -9 EXIT DO END IF sResponse = NUL$(MsgSz) ' Allocate memory CopyMem( STRPTR(sResponse), pData, MsgSz ) ' Copy message to local string RetVal = zmq_msg_close(VARPTR(pMsgIn)) IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_msg_close: " + @pzErr FUNCTION = -10 EXIT DO END IF '============= PRINT #hDbg, "Response=" + sResponse ' @pData MSGBOX sResponse,64,"Server Response" EXIT DO LOOP SLEEP 1 ' CALL zmq_sleep(1) IF pSoc THEN RetVal = zmq_close(pSoc) IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_close: " + @pzErr FUNCTION = -11 EXIT FUNCTION END IF END IF '============= RetVal = zmq_term(pCtx) IF RetVal < 0 THEN pzErr = zmq_strerror(zmq_errno) PRINT #hDbg, "error"+STR$(zmq_errno)+" in zmq_term: " + @pzErr FUNCTION = -12 EXIT FUNCTION END IF '============= FUNCTION = 0 END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤' FUNCTION WINMAIN LOCAL hDlg, RetVal AS LONG LOCAL tWSA AS WSAData WSAStartup(&H0202?, tWSA) ' Always initialize WSAStartUp in applications using Sockets hDbg = FREEFILE : OPEN $DEBUG_FILE FOR OUTPUT LOCK SHARED AS hDbg ' PRINT #hDbg, "-------- "+DATE$+" "+TIME$+" ---------" RetVal = SendMessageZmq( "tcp://localhost:5555" ) IF RetVal < 0 THEN PRINT #hDbg, "Server Failed Error=" + STR$(RetVal) END IF WSACleanup() PRINT #hDbg, "All Done" CLOSE #hDbg END FUNCTION '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤' powerbasic |