云渲染支持通过集成CGProxy SDK实现渲染程序与H5 SDK之间的数据交流。
前提条件
- 引入H5 SDK。更多信息,请参见GCS SDK for H5。
- 下载CGProxy SDK安装包。
背景信息
渲染程序目前可以接收H5 SDK发送的数据,但不能对数据做任何处理。渲染程序集成CGProxy SDK可以与H5 SDK之间进行数据交流。
CGProxy SDK
初始化接口
启动渲染程序时,通过解析接收的命令行参数获取需要监听的地址和端口,用于接收指令流。
- 传入参数
参数说明: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
。
- 调用初始化接口。
调用初始化接口,获取处理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);
参数说明:- 当
ip
和port
有效时,渲染程序发送数据到指定的地址。 - 当
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