Skip to content

Multi-language Client Implementation

Below are official libraries for common programming languages to connect and call iClick API.

Quick Installation

Node.js, Python, and C# users can directly install via package managers without manually implementing clients:

All these packages implement API calls, event listening, and MetaData binary stream parsing.

Other Languages

The following code examples may not be fully verified and are for reference and learning purposes only. Please ensure thorough testing and validation before using in production environments.

javascript
const wserverPort = 23188
const wsevents = {}
let wsclient = null
let reconnectTimer = null

export function reconnect() {
    if( reconnectTimer || wsclient?.readyState === WebSocket.CONNECTING ){
        return
    }
    reconnectTimer = setTimeout(() => {
        console.log('API service reconnecting...')
        connectServer().finally(() => reconnectTimer = null)
    }, 1000 * 3)
}

export function connectServer() {
    return new Promise((_resolve) => {
        
        if( wsclient ){
            return
        }

        wsclient = new WebSocket(`ws://127.0.0.1:${wserverPort}`)
        wsclient.binaryType = 'arraybuffer'

        wsclient.onopen = () => {
            console.log('API service connected successfully')
            _resolve()
        }

        wsclient.onmessage = (_message) => {
     
            let _payload = _message.data,
                _bindata = null

            if( typeof _payload === 'string' ){

                _payload = JSON.parse(_payload)

            }else{

                // Some interfaces return binary data, need to parse [metaDataLength][metaData][binary]
                const _decoder = new TextDecoder('utf-8')   
                const _metaLength = _decoder.decode(_payload.slice(0, 6))
                                    _bindata = _payload.slice(6 + parseInt(_metaLength))
                                    _payload = JSON.parse(_decoder.decode(_payload.slice(6, 6 + parseInt(_metaLength))))
                _payload.data = _bindata
                _bindata = null
            }
            
            const _eventId = _payload.evtid
            const _event = wsevents[ _eventId ]
  
            if( _event ){

                if( _payload.type === 'error' ){
                    _event.reject(new Error(_payload.error))
                }else{
                    _event.resolve( _payload.data )
                }

                delete wsevents[ _eventId ]

            }else if( _payload.event ){

                // You can dispatch events according to different languages
            }
        }
        
        wsclient.onclose = (code) => {

            wsclient = null
            console.log('API service connection closed:', code)
            reconnect()
        }
        
        wsclient.onerror = (err) => {
            console.error('API service connection error:', err)
        }
    })
}


export function apiInvoke(type, _params = {}, _timeout = 18) {

    return new Promise((resolve, reject) => {

        if( !wsclient || wsclient.readyState !== WebSocket.OPEN ){

            reject( new Error('API service connection not ready') )

        }else{

            const _eventId = Math.random().toString(36).substring(2, 12)
            const _payload = {
                ..._params,
                type,
                evtid: _eventId,
                timeout: _timeout
            }

            wsevents[_payload.evtid] = { resolve, reject }

            wsclient.send(JSON.stringify(_payload))

            if( _timeout > 0 ){
                setTimeout(() => {

                    reject(new Error(`API service: ${_payload.evtid} Invoke Timeout !`))

                    delete wsevents[_payload.evtid]

                }, _timeout * 1000)
            }
        }
    })
}

// Usage example
await connectServer()
const result = await apiInvoke('click', { x: 100, y: 200, deviceId: 'XXXXXXXXXX' })

Next Steps

  • Read more specific API usage examples

Cooperation: try.catch@foxmail.com