BASIC ZMQ Client

' 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



Comments