适用场景
- 客户端程序需要使用授权网关,但不希望让客户手工配置转发地址和成员账号。
- 授权网关功能与客户端集成,透明接入,授权网关通讯跟随客户端程序开启和关闭。
接入要求
- 需要有项目源码,开发环境正常可重新编译发布。
- 具备一定的开发能力,可根据 API 文档和程序样例加入 SDK 启动代码
准备素材
- 准备项目源码和开发环境,测试可正常编译。
- 下载 SDK 文件(点此下载),将 gateway.dll 文件复制到项目中,确保与 exe 程序文件在相同目录,注意区分 32 位和 64 位版本。
注意事项
- SDK 加载流程为:
(1)加载 dll
(2)调用启动函数
(3)调用更新函数,加载配置
(4)正常运行过程直到需要关闭
(5)调用停止函数
(6)卸载 dll
退出程序前一定要调用停止函数,否则可能造成进程死锁。 - Windows 平台下请使用 WINAPI 宏修饰函数,函数名称无 @ 后缀,与系统函数风格相同。
加载说明
函数说明(按 C 语言)
1. gateway_start
int gateway_start(); 功能:启动网关 返回:成功返回 0
2. gateway_stop
int gateway_stop(); 功能:停止网关 返回:总是返回 0
3. gateway_update
int gateway_update(const char* config); 功能:更新配置 参数:config 是一个标准 C 字符串,包含 JSON 格式配置。 返回:成功返回 0
4. gateway_status
int gateway_status(char* buffer, int size); 功能:获取状态 参数:buffer 需提供一个缓冲区用于接收内容,size 为缓冲区大小。收到的内容是一个 JSON 格式文本。 返回:成功返回实际内容长度,错误或缓冲不足返回 0。
样例程序
- 引入头文件并声明函数
#include <windows.h> #include <stdio.h> #include <string.h> // 定义函数指针类型 typedef int WINAPI (*GATEWAY_START)(); typedef int WINAPI (*GATEWAY_STOP)(); typedef int WINAPI (*GATEWAY_UPDATE)(const char*); typedef int WINAPI (*GATEWAY_STATUS)(char*, int); // 全局变量来保存 DLL 模块句柄和函数指针 HINSTANCE hDLL = NULL; GATEWAY_START gateway_start = NULL; GATEWAY_STOP gateway_stop = NULL; GATEWAY_UPDATE gateway_update = NULL; GATEWAY_STATUS gateway_status = NULL;
- 加载
// 加载 DLL 并获取函数地址 bool loadDll() { // 加载DLL hDLL = LoadLibrary(TEXT("gateway.dll")); if (hDLL == NULL) { printf("无法加载动态库\n"); return false; } // 获取函数地址 gateway_start = (GATEWAY_START)GetProcAddress(hDLL, "gateway_start"); gateway_stop = (GATEWAY_STOP)GetProcAddress(hDLL, "gateway_stop"); gateway_update = (GATEWAY_UPDATE)GetProcAddress(hDLL, "gateway_update"); gateway_status = (GATEWAY_STATUS)GetProcAddress(hDLL, "gateway_status"); if (!gateway_start || !gateway_stop || !gateway_update || !gateway_status) { printf("无法获取函数地址\n"); FreeLibrary(hDLL); return false; } return true; }
- 释放
// 释放 DLL void unloadDll() { if (hDLL != NULL) { gateway_start = NULL; gateway_stop = NULL; gateway_update = NULL; gateway_status = NULL; FreeLibrary(hDLL); hDLL = NULL; } }
- 使用 main 函数演示生命周期
int main() { // 加载 DLL if (!loadDll()) return 1; // 启动网关 int ret = gateway_start(); if (ret != 0) { printf("无法启动: %d\n", ret); unloadDll(); return 1; } // 更新配置(注意是一个 JSON 的数组,可以放多个转发配置,id 为自定义序号) const char* config = "[\n" " {\n" " \"id\": 1,\n" " \"remote\": \"lyxtest.a1.luyouxia.net:12345\",\n" " \"listen\": \"127.0.0.1:8888\",\n" " \"name\": \"成员账号名称\",\n" " \"pwd\": \"成员密码的 MD5 值\"\n" // " }\n" "]"; ret = gateway_update(config); if (ret != 0) { printf("无法更新配置: %d\n", ret); gateway_stop(); unloadDll(); return 1; } printf("成功更新配置\n"); // 模拟运行过程(持续显示状态,一段时间后关闭) for (int i = 0; i < 60; i++) { char buf[1024] = {0}; if (gateway_status(buf, sizeof(buf)) > 0) printf("状态: \n%s\n", buf); Sleep(1000); // 等待1秒 } // 停止网关 gateway_stop(); printf("已停止\n"); // 释放 DLL unloadDll(); return 0; }
关于配置格式
配置格式是一个 JSON 数组,元素为每一个转发项,如果直接填写到测试代码中,请注意转义,线上系统建议远程加载或本地配置文件读取。程序可以重复调用 gateway_update 动态更新。
[ { "id": 1, "remote": "lyxtest.a1.luyouxia.net:12345", "listen": "127.0.0.1:12345", "name": "成员账号名称", "pwd": "成员密码 MD5 值" }, { "id": 2, "remote": "lyxtest.a1.luyouxia.net:12346", "listen": "127.0.0.1:12346", "name": "成员账号名称", "pwd": "成员密码 MD5 值" } ]