云渲染支持通过集成CGProxy SDK实现渲染程序与H5 SDK之间的数据交流。

前提条件

请确保您已完成以下操作:

背景信息

渲染程序目前可以接收H5 SDK发送的数据,但不能对数据做任何处理。渲染程序集成CGProxy SDK可以与H5 SDK之间进行数据交流。

CGProxy SDK

初始化接口

启动渲染程序时,通过解析接收的命令行参数获取需要监听的地址和端口,用于接收指令流。

  1. 传入参数
    typedef struct CG_Proxy_InitMsg {
        char ip[128];                /* listen ipv4, if null CgProxy will iterator all current ipv4 */
        int port;                    /* listen port */
        CG_Proxy_OnRecv on_recv;        /* callback on recv thread so app should return as quick as possible */
        void* cb_param;
    }CG_Proxy_InitMsg;
    参数说明:
    • ip:渲染程序启动时传入的RTSIP。即RTSIP=127.0.0.1。
    • port:渲染程序启动时传入的PTSPORT
  2. 调用初始化接口。

    调用初始化接口,获取处理H5 SDK消息的权限。

    /**
     * @brief Init
     * @param initmsg
     * @return CG_Proxy_Errno
     */
    int EXRTS_DECL CG_Proxy_Init(const CG_Proxy_InitMsg* init);                

接收数据接口

实现接收数据接口,接收H5 SDK向渲染程序发送的数据。

/* msg callback */
typedef int (__stdcall *CG_Proxy_OnRecv)(void* cb_param, void* data, int data_len);
参数说明:

cb_param:初始化命令时传入的参数。

发送数据接口

调用发送数据接口,实现渲染程序向H5 SDK发送数据。

/**
 * @brief Send
 * @param ip/port if valid CgProxy sendto ip+port, if null CgSxd will sendto all remote peer that haved receive data
 * @param data
 * @param data_len
 * @return CG_Proxy_Errno
 */
int EXRTS_DECL CG_Proxy_Send(const char* ip, int port, const char* data, int data_len);
参数说明:
  • ipport有效时,渲染程序发送数据到指定的地址。
  • ip=null或port=0时,向H5 SDK发送数据。

退出接口

调用退出接口,取消渲染程序与H5 SDK之间交流的权限。
/**
 * @brief UnInit
 * @return CG_Proxy_Errno
 */
int EXRTS_DECL CG_Proxy_UnInit();

模板示例

  • 以下为测试渲染程序是否可以成功接收并发送数据的完整示例。
    #include "../src/cg_sxd_interface.h"
    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <string>
    #include <winsock2.h>
    #pragma comment(lib, "WS2_32.lib")
    
    int Proxy_OnLog(void* cb_param, CG_Sxd_Log_Level level, const char* str) {
        printf("OnLog %s\n", str);
        return 0;
    }
    
    int Proxy_OnRecv(void* cb_param, void* data, int data_len) {
        printf("OnRecv len=%d\n", data_len);
        return 0;
    }
    static int g_lport = 0;
    static int g_rport = 0;
    static std::string g_ip = "";
    
    int main(int argc, char* argv[]) {
        WSADATA wsaData;
        if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) {
            return 0;
        }
        std::cout << "testserver localport 0 remoteip" << std::endl;
        std::cout << "testserver localport remoteport remoteip" << std::endl;
        int input = 0;
        if (argc < 4) {
            return 0;
        }
        else {
            g_lport = std::stoi(argv[1]);
            g_rport = std::stoi(argv[2]);
            g_ip = argv[3];
            CG_Proxy_SetLog(nullptr, Proxy_OnLog, CG_Proxy_LOG_DBG);
            CG_Proxy_InitMsg msg = { 0 };
            snprintf(msg.ip, sizeof(msg.ip), "%s", g_ip.c_str());
            msg.port = g_lport;
            msg.on_recv = Proxy_OnRecv;
            CG_Proxy_Init(&msg);
            while (true) {
                std::cin >> input;
                if (0 == input) {
                    break;
                }
                char msg_buf[128] = { 0 };
                memset(msg_buf, input % 26, sizeof(msg_buf));
                CG_Proxy_Send(g_ip.c_str(), g_rport, msg_buf, sizeof(msg_buf));
            }
            CG_Proxy_UnInit();
        }
        WSACleanup();
        return 0;
    }
    
    // 启动udp server
    // udp client启动后,输入非0字符,发送接收一次数据
    test 9000 0 127.0.0.1
  • 以下为模拟H5 SDK向渲染程序发送数据或接收数据的完整示例。
    #include <iostream>
    #include <thread>
    #include <chrono>
    #include <string>
    #include <winsock2.h>
    #pragma comment(lib, "WS2_32.lib")
    
    static bool g_send_run = true;
    static int g_rport = 0;
    static std::string g_ip = "";
    
    void Proxy_Send_Test() {
        struct sockaddr_in addr;
        int addr_len = sizeof(addr);
        int64_t sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock_fd < 0) {
            printf("create sock fail\n");
            return;
        }
        addr.sin_family = AF_INET;
        addr.sin_port = htons(g_rport);
        addr.sin_addr.s_addr = inet_addr(g_ip.c_str());
        char msg_buf[128] = { 0 };
    
        struct sockaddr_in remote;
        int remote_len = sizeof(remote);
        while (g_send_run) {
            int ret = sendto(sock_fd, msg_buf, sizeof(msg_buf), 0, (struct sockaddr*)&addr, addr_len);
            if (ret <= 0) {
                printf("sendto fail\n");
            }
            ret = recvfrom(sock_fd, msg_buf, sizeof(msg_buf), 0, (struct sockaddr*)&remote, &remote_len);
            if (ret > 0) {
                printf("recvfrom ip=%s, port=%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(200));
        }
        closesocket(sock_fd);
    }
    
    int main(int argc, char* argv[]) {
        WSADATA wsaData;
        if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) {
            return 0;
        }
        std::cout << "testclient remoteport remoteip" << std::endl;
        int input = 0;
        if (argc < 3) {
            return 0;
        }
        else {
            g_rport = std::stoi(argv[1]);
            g_ip = argv[2];
            std::thread send(Proxy_Send_Test);
            std::cin >> input;
            g_send_run = false;
            if (send.joinable()) {
                send.join();
            }
        }
        WSACleanup();
        return 0;
    }
    
    // 启动udp client
    test 9000 127.0.0.1