本文介绍如何在 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 协议的加速。
下文以 Gradle 为例实现 JitPack 集成。
在 /Gradle Scripts/build.gradle(Project: <projectname>)
文件中添加如下代码,添加 JitPack 依赖:
allprojects {
repositories {
...
maven { url 'https://www.jitpack.io' }
}
}
在 /Gradle Scripts/build.gradle(Module: .app)
文件中添加依赖项,将 SDK 集成到你的 Android 项目中:
dependencies {
...
implementation 'com.github.agorabuilder:fpa:1.2.1'
...
}
请使用最新版本的声网 SDK 集成。版本号及 JitPack 在其他集成工具上的集成方法(maven、sbt、leiningen)参考:https://jitpack.io/#agorabuilder/fpa 。
如果你需要使用离线 SDK 包集成,参考 其它集成方式。
在 /app/Manifests/AndroidManifest.xml
文件中的 </application>
后面添加如下网络权限:
<uses-permission android:name="android.permission.INTERNET" />
你必须初始化 SDK 并开启 FPA 服务之后才能实现 SDK 的全链路加速功能。
确保在项目中 import 以下类。
import io.agora.fpa.proxy.FpaProxyConnectionInfo;
import io.agora.fpa.proxy.FpaProxyService;
import io.agora.fpa.proxy.FpaProxyServiceConfig;
import io.agora.fpa.proxy.FpaHttpProxyChainConfig;
import io.agora.fpa.proxy.FpaChainInfo;
import io.agora.fpa.proxy.IFpaServiceListener;
import io.agora.fpa.proxy.LogLevel;
创建一个 FpaProxyServiceConfig
对象,设置 App ID、token、日志等相关参数。
private String workDir;
private FpaProxyServiceConfig config;
File workDirFile = new File(getCacheDir().getAbsoluteFile() + "/agora/fpa_log_sdk.log");
workDir = workDirFile.getAbsolutePath();
// 在 Builder 方法中设置日志文件路径
// 后续查看日志文件路径可以参考 Builder 方法参数的值
FpaProxyServiceConfig.Builder builder = new FpaProxyServiceConfig.Builder(workDir);
// 设置 App ID
builder.setAppId("<Your App ID>")
// 设置 token。如果不开启 Token 鉴权,可无需调用 setToken()
.setToken("<Your Token>")
// 设置日志文件大小
.setLogFileSizeKb(1024)
// 设置日志级别
.setLogLevel(LogLevel.LOG_ERROR);
config = builder.build();
设置代理回调监听器并开启 FPA 服务。
// 设置代理事件回调监听器
FpaProxyService.getInstance().setListener(new IFpaServiceListener() {
// 连接 FPA 代理成功
@Override
public void onConnected(@Nullable FpaProxyConnectionInfo info) {
Log.e(TAG, "[JAVA] onConnected. info=" + info);
}
// FPA 代理加速成功
@Override
public void onAccelerationSuccess(@Nullable FpaProxyConnectionInfo info) {
Log.e(TAG, "[JAVA] onAccelerationSuccess. info=" + info);
}
// 连接 FPA 代理失败且未回退
@Override
public void onConnectionFailed(@Nullable FpaProxyConnectionInfo info, FailedReason reason) {
Log.e(TAG, "[JAVA] onConnectionFailed. info=" + info + " reason: " + reason.getDesc());
}
// 连接 FPA 代理失败且回退至本地连接
@Override
public void onDisconnectedAndFallback(@Nullable FpaProxyConnectionInfo info, FailedReason reason) {
Log.e(TAG, "[JAVA] onDisconnectedAndFallback. info=" + info + " reason: " + reason.getDesc());
}
});
// 开启 FPA 服务
FpaProxyService.getInstance().start(config);
本文以 OkHttp 库为例,通过 SDK 处理 HTTP 请求与响应。你也可以使用其他支持设置修改 HTTP 代理发送请求的 HTTP 库。
通过 setOrUpdateHttpProxyChainConfig
方法设置源站 IP 地址或域名与 chain ID 的映射表,通过 setListener
方法设置代理事件回调监听器。
String[] cas = new String[0];
FpaHttpProxyChainConfig.Builder builder = new FpaHttpProxyChainConfig.Builder();
// 设置 FPA 服务的 chain ID,例如 123
// 设置源站 IP 地址或域名
// 设置源站端口,例如 80
// 设置是否允许此加速通道在 FPA 代理连接失败时回退到本地连接
// 回退链路加密相关设置,在这里选择关闭
builder.addChainInfo(123, "<Your IP or domain>", 80, true, false, cas, "")
// 设置是否在 HTTP 本地代理在 FPA SDK 找不到源站对应的 chain ID 时回退到本地连接
.fallbackWhenNoChainAvailable(true);
FpaProxyService.getInstance().setOrUpdateHttpProxyChainConfig(builder.build());
基于 OkHttpClient
类创建一个 okHttpClient
对象,并使用这个对象注册 FpaService
对象提供的内部 HTTP 代理。
FpaProxyService
对象和 okhttpClient
对象的生命周期是绑定的,如果你调用 stop
销毁了创建的 FpaProxyService
实例,和 FpaProxyService
绑定的 okHttpClient
也无法发送 HTTP 请求到 FPA 服务。// 基于 OkHttpClient 类创建一个 okHttpClient 对象
okHttpClient = new OkHttpClient.Builder()
.readTimeout(300,TimeUnit.SECONDS)
.writeTimeout(300,TimeUnit.SECONDS)
// 将 okHttpClient 对象绑定到 FpaProxyService 提供的内部 HTTP 代理中。在生产环境下,此处建议增加判断逻辑,在 getHttpProxyPort()<=0 时不使用 FPA 代理
.proxy(new Proxy(HTTP, new InetSocketAddress("127.0.0.1", FpaProxyService.getInstance().getHttpProxyPort())))
.build();
如果你的项目中已经创建了 okHttpClient
对象(示例代码中为 oldOkHttpClient
),可以通过 newBuilder()
方法更新对象的 proxy 属性。
okHttpClient = oldOkHttpClient.newBuilder()
// 注册 FpaProxyService 对象提供的内部 HTTP 代理
.proxy(new Proxy(HTTP, new InetSocketAddress("127.0.0.1", FpaProxyService.getInstance().getHttpProxyPort())))
.build();
使用注册 FpaProxyService
代理的 okHttpClient
对象发送 HTTP 请求并处理 HTTP 响应。
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
}
});
}
本文以 java.net.Socket
库为例,通过 SDK 处理 socket 请求与响应。你也可以使用其他 socket 库实现透明代理功能。
你已经完成了 SDK 初始化并开启了 FPA 服务。详见初始化 SDK 并开启 FPA 服务。
通过 getTransparentProxyPort
方法获取透明代理端口。
// 设置 FPA 服务的 chain ID,例如 123
int chainId = 123;
// 设置源站域名或 IP
String address = "<Your domain or IP>";
// 通过 port 参数设置源站端口,例如 30103
int port = 30103;
// 设置是否允许此加速通道在 FPA 代理连接失败时回退到本地连接
boolean enableFallback = true;
// 回退链路加密设置。在这里设为 false
boolean enableCrypto = false;
String[] userCas = new String[0];
String verifyHost = "";
FpaChainInfo chainInfo = new FpaChainInfo(chainId, address, port, enableFallback, enableCrypto, userCas, verifyHost);
// 调用 getTransparentProxyPort 获取透明代理的端口
// 在生产环境下,此处建议增加判断逻辑,在 t_port <= 0 时不使用 FPA 代理
int t_port = FpaProxyService.getInstance().getTransparentProxyPort(chainInfo);
通过获取的端口连接透明代理。
socket = new Socket();
socket.connect(new InetSocketAddress("127.0.0.1", t_port));
成功连接之后,即可通过透明代理进行 socket 数据发送和接收。
下文以 Gradle 为例实现手动复制 SDK 文件的集成方式。
在 SDK 下载 页面下载最新版本的声网 FPA SDK,并解压。将 SDK 包中的以下文件或子文件夹复制到你的 Android 项目路径中。
文件或子文件夹 | 项目路径 |
---|---|
jar 文件 |
/app/libs/ |
arm64-v8a 文件夹 |
/app/src/main/jniLibs/ |
armeabi-v7a 文件夹 |
/app/src/main/jniLibs/ |
x86 文件夹 |
/app/src/main/jniLibs/ |
x86_64 文件夹 |
/app/src/main/jniLibs/ |
在 /Gradle Scripts/build.gradle(Module: .app)
文件中添加依赖项,将 SDK 集成到你的 Android 项目中:
dependencies {
...
implementation fileTree(dir: 'libs', include: [ '*.jar' ])
...
}
FpaProxyServiceConfig.Builder(logFile)
方法设置。你需要自行在 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;
}