客户端开发

更新时间:
2024-11-26
下载文档

客户端开发

本节内容介绍 VSOA 客户端使用 VSOA Datagram 的方法。

开发须知

客户端和服务端建立连接后,双方均可发送和接收 VSOA Datagram。发送使用直接调用函数方式;而接收使用事件机制,需要绑定一个接收回调函数。

常用接口

void vsoa_client_on_datagram(vsoa_client_t *client, vsoa_client_dat_func_t callback,
                             void *arg);

bool vsoa_client_datagram(vsoa_client_t *client, const vsoa_url_t *url,
                          const vsoa_payload_t *payload);

bool vsoa_client_quick_datagram(vsoa_client_t *client, const vsoa_url_t *url, const vsoa_payload_t *payload);
client.datagram(url, payload[, quick]);

client.on('datagram', function(url, payload, quick));
void Client.onDatagram(String url, Payload payload, boolean quick);

boolean client.datagram(String url, Payload payload, boolean quick);
func (client *Client) Call(URL string, mt protocol.MessageType, flags any, req *protocol.Message) (*protocol.Message, error)
client.datagram(url: str, payload: vsoa.Payload | dict = None, quick: bool = False) -> bool
client.ondata(cli: Client, url: str, payload: vsoa.Payload | dict = None, quick: bool = False)

说明:

VSOA Datagram 客户端的详细接口说明可参考以下手册:

开发示例

在本示例中,客户端执行以下流程:

  1. 连接 VSOA 服务器 vsoa_datagram_server
  2. 绑定一个 Datagram 接收事件的回调函数 datagram_callback
  3. 在回调函数中,打印收到的数据,并将数据原封不动发送给服务端。

运行成功时,客户端有如下输出:

  1. 在成功连接到 VSOA 服务器后,打印 Connected to VSOA datagram server
  2. 在成功接收服务器发送的数据后,打印 Datagram received from URL /axis with payload:,后面带有收到的数据。

普通发送方式

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef SYLIXOS
#include <sys/vproc.h>
#endif
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#include "vsoa_client.h"
#include "vsoa_cliauto.h"
#include "vsoa_position.h"

static void datagram_callback(void *arg, vsoa_client_t *client, vsoa_url_t *url,
                              vsoa_payload_t *payload, bool quick)
{
    printf("Datagram received from URL %.*s with payload: %.*s\n",
           (int)url->url_len, url->url, (int)payload->param_len, payload->param);

    // send datagram to server (echo)
    vsoa_client_datagram(client, url, payload);
}

static void connect_callback(void *arg, vsoa_client_auto_t *cliauto,
                             bool connect, const char *info)
{
    vsoa_client_t       *client;
    vsoa_url_t           url;

    if (!connect) {
        fprintf(stderr, "Cannot connect to VSOA stream server.\n");
        return;
    }

    printf("Connected to VSOA datagram server.\n");

    // get client handle
    client  = vsoa_client_auto_handle(cliauto);

    // register datagram callback
    vsoa_client_on_datagram(client, datagram_callback, NULL);
}

int main(int argc, char *argv[])
{
    vsoa_client_auto_t  *cliauto;

#ifdef SYLIXOS
    vprocExitModeSet(getpid(), LW_VPROC_EXIT_FORCE);
#endif

    /*
     * Create client auto robot
     */
    cliauto = vsoa_client_auto_create(NULL, NULL);

    /*
     * Add a connection callback
     * The callback is called automatically when client is connected to the server.
     */
    if (!vsoa_client_auto_setup(cliauto, connect_callback, NULL)) {
        vsoa_client_auto_delete(cliauto);
        fprintf(stderr, "Cannot register connect callback: %s (%d)\n", strerror(errno), errno);
        return -1;
    }

    /*
     * Client auto robot start
     * The robot will automatically connect to the specified server and maintain the connection.
     * At this time, the developer only needs to focus on the business.
     */
    vsoa_client_auto_start(cliauto, "vsoa://vsoa_datagram_server", NULL, NULL, 0, 1000, 1000, 1000);

    while (true) {
        sleep(1);
    }

    return 0;
}
var vsoa = require('vsoa');

/* Server name to connect */
var SERVER_NAME = "vsoa_datagram_server"

/* Client */
var client = new vsoa.Client();

/* Receive datagram */
client.on('datagram', function(url, payload, quick) {
    console.log('Datagram received from URL ' + url +
                ' with payload: ' + JSON.stringify(payload.param))
    client.datagram(url, payload)
})

client.connect(`vsoa://${SERVER_NAME}`, error => {
    if (error) {
        console.error('Cannot connect to VSOA stream server.');
    } else {
        console.log('Connected to VSOA datagram server.')
    }
});

/*
 * Event loop
 */
require('iosched').forever();
import java.net.InetSocketAddress;

import com.acoinfo.vsoa.*;
import com.acoinfo.vsoa.Error;

public class datagram_client {
    private static boolean  POS_MANUALLY = true;
    private static String   SERVER_NAME  = "vsoa_datagram_server";
    private static String   POS_ADDRESS  = "0.0.0.0";
    private static int      POS_PORT     = 3012;

    public static Client client;

    public static void main(String[] args) {

        /*
         * Initialize client
         */
        client = new Client(new ClientOption(null, 6000, 4000, 3, false)) {

            @Override
            public void onError(Error error) {
                System.out.println("Client error:" + error.message);
            }

            @Override
            public void onConnected(String info) {
                System.out.println("Connected to VSOA datagram server.");
            }

            @Override
            protected void onDatagram(String url, Payload payload, boolean quick) {
                System.out.println("Datagram received from URL " + url +
                                   " with payload: " + payload.param);
                this.datagram(url, payload);
            }
        };

        if (!client.connect("vsoa://" + SERVER_NAME, null, Constant.VSOA_DEF_CONN_TIMEOUT)) {
            System.out.println("Connected with server failed");
            return;
        }


        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
package main

import (
    "encoding/json"
    "fmt"
    "strconv"

    "gitee.com/sylixos/go-vsoa/client"
    "gitee.com/sylixos/go-vsoa/protocol"
)

var roll, pitch, yaw int = 1, 1, 1

// VsoaDatagramCall is a function that sends a datagram call using the VSOA protocol.
//
// It connects to the VSOA server at "localhost:3001" and sends a datagram message
// with the parameter `{"Test Datagarm": "Normal Channel"}`. The function prints an
// error if there was a problem connecting to the server or sending the datagram
// message. Otherwise, it prints "Datagram send done" to indicate a successful send.
func VsoaDatagramCall() {
    // Set client options
    clientOption := client.Option{
        Password: "123456",
    }

    // Create a new client instance
    c := client.NewClient(clientOption)

    // Connect to the VSOA server
    _, err := c.Connect("vsoa", "localhost:3001")
    if err != nil {
        fmt.Println(err)
        return
    }

    // Close the connection when the function exits
    defer c.Close()

    // Create a new message
    req := protocol.NewMessage()

    // Set the message parameter
    req.Param, _ = json.RawMessage(`{"roll":` + strconv.Itoa(roll) +
        `, "pitch":` + strconv.Itoa(pitch) +
        `, "yaw":` + strconv.Itoa(yaw) + `}`).MarshalJSON()

    // Send the datagram call
    _, err = c.Call("/axis", protocol.TypeDatagram, protocol.ChannelNormal, req)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Datagram /axis send done")
    }
}

func main() {
    VsoaDatagramCall()
}

from vsoa.client import Client
import vsoa

# Server name to connect
SERVER_NAME = 'vsoa_datagram_server'

client = Client()

# Receive datagram
def ondata(cli: Client, url: str, payload: vsoa.Payload | dict = None, quick: bool = False):
    print('Datagram received from URL {} with payload: {}'.format(url, str(payload.param)))
    cli.datagram(url, payload)

client.ondata = ondata

# Client connect
if err := client.connect('vsoa://{}'.format(SERVER_NAME)):
    print('Connect error: {}'.format(err))
    sys.exit(-1)

# Event loop
client.run()

说明:

  • 在 Node.js 环境中,不需要最后的事件循环操作,需要去除 require('iosched').forever();
  • 在该范例中,因为使用了独立的位置服务或 ECSM 集成的位置服务,所以客户端可以自动定位到指定的服务位置,不需要指定任何 IP 和端口信息。

快速发送方式

C 语言环境

对于 C 语言环境,将如下接口进行替换即可:

// send datagram to server (echo)
vsoa_client_datagram(client, url, payload);

修改后:

// send datagram to server (echo)
vsoa_client_quick_datagram(client, url, payload);

JavaScript 语言环境

对于 JavaScript 语言环境 将 datagram 的最后一个参数设置为 true 即可:

 client.datagram(url, payload);

修改后:

 client.datagram(url, payload, true);

Java 语言环境

对于 Java 语言环境,将 datagram 的最后一个参数设置为 true 即可:

 this.datagram(url, payload);

修改后:

 this.datagram(url, payload, true);

Go 语言环境

对于 Go 语言环境,将参数 protocol.ChannelNormal 修改为 protocol.ChannelQuick 即可:

 _, err = c.Call("/axis", protocol.TypeDatagram, protocol.ChannelNormal, req)

修改后:

 _, err = c.Call("/axis", protocol.TypeDatagram, protocol.ChannelQuick, req)

Python 语言环境

对于 Python 语言环境,将 datagram 的最后一个参数设置为 true 即可:

 cli.datagram(url, payload)

修改后:

 cli.datagram(url, payload, true)

注意事项

C/C++ 客户端编译时需链接如下表所示的 VSOA 动态库,在 RealEvo-IDE 中配置时请参考 C/C++ 环境验证,Linux 下开发请参考 搭建 Linux 运行环境 提供的 C 语言范例进行配置。

库名称功能
libvsoa-json.so提供 JSON 功能
libvsoa-client.so提供客户端功能
libvsoa-parser.so提供参数解析功能
libvsoa-position.so位置服务功能
文档内容是否对您有所帮助?
有帮助
没帮助