本文介绍如何在 SDK 模式下实现加速。
全链路加速 SDK 的基本使用流程如下。
创建 FPA 服务并获取 FPA 服务的 chain ID、源站域名/IP 和端口。详见开通服务。
获取 App ID。详见获取 App ID。 -(可选)获取 App 证书。详见获取 App 证书。
(可选)在 App 服务端生成 Token。详见生成 Token。
SDK 支持通过本地 HTTP 代理和本地 TCP 透明代理实现加速。
SDK 以本地 HTTP 代理的方式,将 app 通过 HTTP 库发出的 HTTP 请求和源站服务器返回的 HTTP 响应转化为 FPA SDK 与声网服务器之间的私有协议连接,从而实现基于 HTTP 协议的加速。
HTTP 库需要支持设置修改 HTTP 代理发送请求。
SDK 以本地 TCP 透明代理的方式,将 app 通过 socket 库建立的 TCP 连接转化为 FPA SDK 与声网服务器之间的私有协议连接,从而实现基于 TCP 协议的加速。
如果你的目标平台为 iOS,你的开发环境需要满足以下需求:
如果你的目标平台为 Android,你的开发环境需要满足以下需求:
目前 FPA Flutter SDK 仅支持移动端。
flutter doctor
命令检查开发环境和运行环境是否满足要求。在你的 Flutter 项目的 pubspec.yaml
文件中添加以下依赖项:
添加 agora_fpa_service
依赖项,集成声网 Flutter SDK。关于 agora_fpa_service
的最新版本可以查询 https://pub.dev/packages/agora_fpa_service 。
environment:
sdk: ">=2.12.0 <3.0.0"
# 依赖项
dependencies:
flutter:
sdk: flutter
# FPA Flutter SDK 依赖项,请使用最新版本的 agora_fpa_service
agora_fpa_service: ^1.0.0
你必须初始化 SDK 并开启 FPA 服务之后才能实现 SDK 的全链路加速功能。
确保在项目中 import 以下 package。
import 'package:agora_fpa_service/agora_fpa_service.dart';
创建一个 FpaProxyServiceConfig
对象,设置 App ID、token、日志等相关参数。
// 通过 getApplicationDocumentsDirectory 设置日志文件路径
late String _logFilePath;
final externalStorage = await getApplicationDocumentsDirectory();
_logFilePath = path.join(externalStorage.absolute.path, 'agora', 'fp_log_sdk.log');
FpaProxyServiceConfig fpaConfig = FpaProxyServiceConfig(
// 设置 App ID
appId: '<Your App ID>',
// 设置 token。如果不开启 Token 鉴权,可不设置 token
token: '<Your token>',
// 设置日志文件大小
logFileSizeKb: 1024,
// 设置日志级别
logLevel: FpaProxyServiceLogLevel.error,
// 设置日志文件储存地址
logFilePath: _logFilePath,
);
通过 setObserver
方法设置代理事件回调监听器并开启 FPA 服务。
// 设置代理事件回调监听器
FpaProxyService.instance.setObserver(this);
try {
FpaProxyService.instance.start(fpaConfig);
} on FpaProxyServiceException catch (e) {
_logSink.sink('start', 'with exception: ${e.toString()}');
return;
}
通过 onAccelerationSuccess
回调、onConnected
回调、onConnectionFailed
回调和 onDisconnectedAndFallback
回调获取 FPA 服务的状态。
// 在 FPA 代理加速成功时触发。你可以在回调中添加逻辑判断 FPA 服务状态并执行对应操作
@override
void onAccelerationSuccess(FpaProxyConnectionInfo info) {
_logSink.sink('onAccelerationSuccess', 'info: ${info.toString()}');
}
// 在成功连接 FPA 代理时触发。你可以在回调中添加逻辑判断 FPA 服务状态并执行对应操作
@override
void onConnected(FpaProxyConnectionInfo info) {
_logSink.sink('onConnected', 'info: ${info.toString()}');
}
// 在连接 FPA 代理失败且连接未回退时触发。你可以在回调中添加逻辑判断 FPA 服务状态并执行对应操作
@override
void onConnectionFailed(
FpaProxyConnectionInfo info, FpaProxyServiceReasonCode reason) {
_logSink.sink(
'onConnectionFailed', 'info: ${info.toString()}, reason: $reason');
}
// 在连接 FPA 代理失败且回退至本地连接时触发。你可以在回调中添加逻辑判断 FPA 服务状态并执行对应操作
@override
void onDisconnectedAndFallback(
FpaProxyConnectionInfo info, FpaProxyServiceReasonCode reason) {
_logSink.sink('onDisconnectedAndFallback',
'info: ${info.toString()}, reason: $reason');
}
本文以 dio 库为例,通过 SDK 处理 HTTP 请求与响应。你也可以使用其他支持设置修改 HTTP 代理发送请求的 HTTP 库。
setOrUpdateHttpProxyChainConfig
方法设置源站 IP 地址或域名与 chain ID 的映射表。FpaHttpProxyChainConfig chainConfig = FpaHttpProxyChainConfig(
// 设置源站 IP 地址或域名与 chain ID 的映射表。
chainArray: [
FpaChainInfo(
// 设置 FPA 服务的 chain ID,例如 123
chainId: 123,
// 源站 IP 地址或域名
address: '<Your domain or IP>',
// 源站端口,例如 80
port: 80,
// 设置是否允许此加速通道在 FPA 代理连接失败时回退到本地连接
enableFallback: true,
),
],
// 开启 HTTP 代理在 FPA SDK 找不到源站对应的 chain ID 时的回退机制
fallbackWhenNoChainAvailable: true,
);
// 调用 setOrUpdateHttpProxyChainConfig 开启设置
FpaProxyService.instance.setOrUpdateHttpProxyChainConfig(chainConfig);
onHttpClientCreate
回调中配置 HttpClient 的本地代理。通过此回调配置 HttpClient 会对整个 _dio
实例生效。// 创建 Dio 对象
_dio = Dio();
// 获取 FPA SDK 本地代理的端口
_fpaPort = FpaProxyService.instance.getHttpProxyPort();
(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) {
// 返回 PROXY $kBaseHost:$port。
// kBaseHost 的值为 "127.0.0.1"
client.findProxy = (uri) {
return 'PROXY ${FpaProxyService.kLocalHost}:$_fpaPort';
};
};
配置完成后,即可使用 _dio
实例发送和接收 HTTP 请求。详见 dio 官方文档。
本文以 dart:io
中的 Socket
类为例,通过 SDK 处理 socket 请求与响应。你也可以使用其他 socket 库实现透明代理功能。
getTransparentProxyPort
方法获取透明代理端口。FpaChainInfo chainInfo = FpaChainInfo(
// 设置 FPA 服务的 chain ID,例如 123
chainId: 123,
// 源站 IP 地址或域名
address: '<Your domain or IP>',
// 源站端口,例如 80
port: 80,
// 设置是否允许此加速通道在 FPA 代理连接失败时回退到本地连接
enableFallback: true,
);
// 调用 getTransparentProxyPort 获取透明代理的端口
// 在生产环境下,此处建议增加判断逻辑,在 _port <=0 时不使用 FPA 代理
int _port = FpaProxyService.instance.getTransparentProxyPort(chainInfo);
late final Socket socket;
try {
socket = await Socket.connect(FpaProxyService.kLocalHost, _port);
} catch (e) {
_logSink.sink(
'TransparentProxy',
'Error in connect socket: ${e.toString()}',
);
}
成功连接之后,即可通过透明代理进行 socket 数据发送和接收。
httpProxyPort
或 getTransparentProxyPortWithChainInfo
获取最新的端口。FpaProxyServiceConfig.logFilePath
属性设置。你可以参考 GitHub 上的 FPA Flutter SDK 示例项目。
你需要自行在 app 服务端部署 Token 生成器。
Token 鉴权的基本逻辑如下图所示。
声网在 GitHub 上提供一个开源的 AgoraDynamicKey 仓库,支持在你自己的服务器上生成 Token。
语言 | 算法 | 核心类 | 生成示例 |
---|---|---|---|
C++ | HMAC-SHA256 | FpaTokenBuilder | FpaTokenBuilderSample.cpp |
Python3 | HMAC-SHA256 | FpaTokenBuilder | fpa_token_builder_sample.py |
本节介绍生成 Token 的 API 参数和描述。 以 C++ 为例:
static std::string BuildToken(
const std::string& app_id,
const std::string& app_certificate);
参数 | 描述 |
---|---|
app_id |
你在声网控制台创建项目时生成的 App ID。 |
app_certificate |
你的项目的 App 证书。 |
下面的 C++ 示例代码展示了如何使用 FpaTokenBuilder
类生成 FPA Token。
#include <iostream>
#include "../src/FpaTokenBuilder.h"
using namespace agora::tools;
int main(int argc, char const *argv[]) {
(void)argc;
(void)argv;
// 你的 App ID
std::string app_id = "970CA35de60c44645bbae8a215061b33";
// 你的 App 证书
std::string app_certificate = "5CFd2fd1755d40ecb72977518be15d3b";
std::string result;
// 生成 FPA token
result = FpaTokenBuilder::BuildToken(app_id, app_certificate);
std::cout << "Token with FPA service:" << result << std::endl;
}