SDK 集成
本文档说明如何将 AuthNexus C++ SDK 集成到客户端应用中,包括线程模型、初始化配置、API 使用与构建集成。
SDK 概览
authnexus_sdk 是一个 C++ 静态库,提供同步 API 接口,内部通过多线程处理异步通讯。
线程模型
SDK 内部维护三个专用线程:
| 线程 | 职责 | 说明 |
|---|---|---|
| Reader 线程 | 接收服务端推送 | 持续读取 TCP 连接上的服务端消息(变量更新、云函数结果、推送通知等) |
| Notify 线程 | 用户回调派发 | 将收到的消息转为回调调用,在独立线程上执行,避免阻塞 reader |
| Heartbeat 线程 | 心跳维持 | 按配置间隔发送心跳包,维持会话活性 |
TIP
所有公开 API 均为同步调用,内部阻塞等待服务端响应。业务层无需处理异步回调(推送消息除外)。
通讯协议
SDK 与 server_app 之间使用 自定义二进制协议(非 HTTP),走 TLS 1.3 + mTLS 加密 TCP 连接。协议定义在 src/core/protocol/ 中。
初始化配置
准备证书文件
集成前需要准备以下证书文件(从管理后台 PKI 页面导出):
| 文件 | 用途 |
|---|---|
tcp_server_ca.pem | 服务端 CA 证书,用于验证服务端身份 |
client.crt | 客户端证书,由 app_client_ca 签发 |
client.key | 客户端私钥 |
ocsp_signer_ca.pem | OCSP 签名 CA,用于验证 OCSP staple(等同于 tcp_server_ca 信任锚点) |
基本初始化
cpp
#include <authnexus/sdk.h>
// 配置连接参数
authnexus::SdkConfig config;
config.server_host = "server.example.com";
config.server_port = 8443;
config.app_id = 1001;
// TLS 证书配置
config.tls.server_ca_path = "certs/tcp_server_ca.pem";
config.tls.client_cert_path = "certs/client.crt";
config.tls.client_key_path = "certs/client.key";
// 可选:OCSP must-staple 验证
config.tls.ocsp_signer_ca_path = "certs/ocsp_signer_ca.pem";
config.tls.ocsp_max_age_seconds = 1800;
// 创建 SDK 实例
authnexus::Sdk sdk(config);心跳配置
cpp
// 心跳间隔(秒),默认值由服务端 server_runtime_settings 下发
config.heartbeat_interval_seconds = 30;连接生命周期
连接建立
SDK 创建
│
▼
TCP 连接 ──► mTLS 握手 ──► OCSP 验证 ──► 连接就绪
│ │
▼ ▼
握手失败 验证失败
(返回错误) (返回错误)登录
cpp
// 登录
authnexus::LoginRequest login_req;
login_req.username = "user@example.com";
login_req.password = "secure_password";
auto login_result = sdk.login(login_req);
if (login_result.success) {
// 登录成功,SDK 自动启动心跳线程维持会话
std::cout << "登录成功,用户ID: " << login_result.user_id << std::endl;
} else {
std::cerr << "登录失败: " << login_result.error_message << std::endl;
}会话维持
登录成功后,SDK 自动:
- 启动 Heartbeat 线程定期发送心跳
- 启动 Reader 线程监听服务端推送
- 启动 Notify 线程处理回调派发
登出与断开
cpp
// 主动登出
sdk.logout();
// SDK 析构时自动断开连接并停止所有内部线程
// 也可显式调用:
sdk.disconnect();API 参考
用户认证
cpp
// 登录
auto result = sdk.login(login_request);
// 登出
sdk.logout();
// 检查连接状态
bool connected = sdk.is_connected();
// 检查登录状态
bool logged_in = sdk.is_logged_in();云函数调用
cpp
// 调用服务端 Lua 云函数
authnexus::CloudFunctionRequest cf_req;
cf_req.function_name = "validate_license";
cf_req.payload = R"({"license_key": "XXXX-YYYY-ZZZZ"})";
auto cf_result = sdk.invoke_cloud_function(cf_req);
if (cf_result.success) {
std::cout << "云函数返回: " << cf_result.response << std::endl;
}变量查询
cpp
// 查询应用级云变量
auto var_result = sdk.get_variable("max_login_attempts");
if (var_result.has_value) {
std::cout << "变量值: " << var_result.value << std::endl;
}推送消息处理
cpp
// 注册推送消息回调(在 Notify 线程上调用)
sdk.on_push_message([](const authnexus::PushMessage& msg) {
std::cout << "收到推送: " << msg.content << std::endl;
// 注意:此回调在 Notify 线程执行,
// 如需操作 UI 请自行转到 UI 线程
});
// 注册连接断开回调
sdk.on_disconnected([](authnexus::DisconnectReason reason) {
std::cerr << "连接断开: " << static_cast<int>(reason) << std::endl;
});错误处理
错误码分类
| 错误码范围 | 类别 | 处理建议 |
|---|---|---|
| 1xxx | 连接错误 | 检查网络和证书配置,尝试重连 |
| 2xxx | 认证错误 | 检查凭据,提示用户重新输入 |
| 3xxx | 业务错误 | 根据具体错误码处理 |
| 4xxx | 服务端错误 | 稍后重试 |
| 5xxx | SDK 内部错误 | 检查 SDK 版本和配置 |
错误处理模式
cpp
auto result = sdk.login(login_req);
if (!result.success) {
switch (result.error_code) {
case 1001: // 连接超时
// 尝试重连
break;
case 2001: // 密码错误
// 提示用户
break;
case 2003: // 用户被禁用
// 提示用户联系管理员
break;
case 2005: // Epoch 已变更,需要重新登录
// 清除本地缓存,重新登录
break;
default:
// 记录日志
break;
}
}重连逻辑
SDK 不内置自动重连,建议业务层实现重连策略:
cpp
// 推荐的重连策略:指数退避
void connect_with_retry(authnexus::Sdk& sdk, int max_retries = 5) {
int delay_ms = 1000;
for (int i = 0; i < max_retries; ++i) {
auto result = sdk.connect();
if (result.success) {
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
delay_ms = std::min(delay_ms * 2, 30000); // 最大 30 秒
}
throw std::runtime_error("无法连接到服务器");
}断开回调中的重连
cpp
sdk.on_disconnected([&sdk](authnexus::DisconnectReason reason) {
if (reason == authnexus::DisconnectReason::NetworkError) {
// 网络错误,启动重连
// 注意:在独立线程中执行,避免阻塞 Notify 线程
std::thread([&sdk]() {
connect_with_retry(sdk);
}).detach();
}
});构建集成
CMake 集成
AuthNexus SDK 作为 CMake 静态库目标提供:
cmake
# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(my_app)
# 添加 AuthNexus SDK(假设源码在 third_party 目录)
add_subdirectory(third_party/authnexus)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE authnexus_sdk)依赖项
SDK 依赖以下库(通过 CMake 自动链接):
- OpenSSL — TLS 1.3 + mTLS 支持
- asio — 异步 IO(header-only)
编译器要求
| 编译器 | 最低版本 | 标准 |
|---|---|---|
| MSVC | VS 2022 (17.x) | C++23 |
| GCC | 13+ | C++23 |
平台说明
Windows:
cmake
# MSVC 需要 /utf-8 编译选项(已在 SDK CMakeLists.txt 中配置)
# 静态链接 MSVC Runtime(/MT 或 /MTd)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")Linux:
cmake
# GCC 需要链接 pthread
find_package(Threads REQUIRED)
target_link_libraries(my_app PRIVATE Threads::Threads)集成示例
完整示例
cpp
#include <authnexus/sdk.h>
#include <iostream>
int main() {
// 1. 配置
authnexus::SdkConfig config;
config.server_host = "auth.mycompany.com";
config.server_port = 8443;
config.app_id = 1001;
config.tls.server_ca_path = "certs/tcp_server_ca.pem";
config.tls.client_cert_path = "certs/client.crt";
config.tls.client_key_path = "certs/client.key";
// 2. 创建 SDK 实例并连接
authnexus::Sdk sdk(config);
// 3. 注册推送回调
sdk.on_push_message([](const authnexus::PushMessage& msg) {
std::cout << "[推送] " << msg.content << std::endl;
});
// 4. 登录
authnexus::LoginRequest req;
req.username = "demo_user";
req.password = "demo_pass";
auto result = sdk.login(req);
if (!result.success) {
std::cerr << "登录失败: " << result.error_message << std::endl;
return 1;
}
std::cout << "登录成功" << std::endl;
// 5. 调用云函数
authnexus::CloudFunctionRequest cf;
cf.function_name = "get_user_profile";
cf.payload = "{}";
auto cf_result = sdk.invoke_cloud_function(cf);
if (cf_result.success) {
std::cout << "用户信息: " << cf_result.response << std::endl;
}
// 6. 查询变量
auto var = sdk.get_variable("app_version");
if (var.has_value) {
std::cout << "当前版本: " << var.value << std::endl;
}
// 7. 业务逻辑运行中...SDK 自动维持心跳
std::cout << "按回车键退出..." << std::endl;
std::cin.get();
// 8. 登出(析构也会自动清理)
sdk.logout();
return 0;
}注意事项
- 线程安全:SDK 的公开 API 都是线程安全的,可以从多个线程并发调用
- 回调线程:推送消息和断开连接回调在 Notify 线程上执行,不要在回调中执行耗时操作
- 证书管理:客户端证书应安全存储,私钥文件权限应限制为仅应用可读
- mTLS 不可选:SDK 强制使用 mTLS,无法绕过或降级为单向 TLS
- 单实例:每个 SDK 实例维护一条 TCP 连接,如需多连接请创建多个实例