Unity BestHTTP 插件完全指南 - 基础篇

BestHTTP 是基于 RFC 2616 的 HTTP/1.1 实现,支持几乎所有 Unity 移动和独立平台。本文档详细介绍其基础用法和高级功能。


一、插件概述

1.1 特性

特性 说明
标准兼容 基于 HTTP/1.1 RFC 2616 规范实现
跨平台 支持几乎所有 Unity 移动和独立平台
易于使用 简洁的 API,强大的功能
线程安全 多线程处理,回调在主线程执行
丰富功能 支持流式下载、缓存、Cookie、代理等

1.2 引入命名空间

1
using BestHTTP;

⚠️ 注意:本文档中的所有示例代码都省略了错误检查,实际使用时请务必添加空值检查。


二、快速入门

2.1 GET 请求

最简单的请求方式是创建 HTTPRequest 对象,提供 URL 和回调函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 方式一:使用命名方法
void StartGetRequest()
{
HTTPRequest request = new HTTPRequest(
new Uri("https://google.com"),
OnRequestFinished
);
request.Send();
}

void OnRequestFinished(HTTPRequest request, HTTPResponse response)
{
if (response != null)
{
Debug.Log("Request Finished! Text received: " + response.DataAsText);
}
else
{
Debug.Log("Request Failed: " + request.Exception);
}
}

// 方式二:使用 Lambda 表达式
void StartGetRequestLambda()
{
new HTTPRequest(new Uri("https://google.com"),
(request, response) => Debug.Log("Finished!")
).Send();
}

2.2 回调函数说明

参数 类型 说明
request HTTPRequest 原始请求对象
response HTTPResponse 服务器响应对象(错误时为 null)

2.3 线程说明

  • 请求处理:在不同线程上处理
  • 回调执行:在 Unity 主线程上执行
  • 无需手动线程同步

三、HTTP 方法

3.1 支持的方法

方法 说明 用途
GET 获取资源 默认方法,获取数据
POST 提交数据 表单提交、数据上传
HEAD 获取头信息 仅获取响应头
PUT 更新资源 上传/替换资源
DELETE 删除资源 删除服务器资源
PATCH 部分更新 部分修改资源

3.2 POST 请求示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 表单方式
void PostForm()
{
HTTPRequest request = new HTTPRequest(
new Uri("http://server.com/path"),
HTTPMethods.Post,
OnRequestFinished
);
request.AddField("FieldName", "Field Value");
request.Send();
}

// Raw Data 方式
void PostRawData()
{
HTTPRequest request = new HTTPRequest(
new Uri("http://server.com/path"),
HTTPMethods.Post,
OnRequestFinished
);
request.RawData = Encoding.UTF8.GetBytes("Field Value");
request.Send();
}

// 其他方法示例
void OtherMethods()
{
// HEAD
new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Head, callback).Send();

// PUT
new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Put, callback).Send();

// DELETE
new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Delete, callback).Send();

// PATCH
new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Patch, callback).Send();
}

四、响应数据处理

4.1 数据获取方式

属性 类型 说明
Data byte[] 原始字节数据
DataAsText string UTF-8 解码的文本
DataAsTexture2D Texture2D 转换为纹理(仅图片)

4.2 下载图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 方式一:手动创建纹理
void DownloadImage()
{
new HTTPRequest(new Uri("http://yourserver.com/path/to/image.png"),
(request, response) =>
{
var tex = new Texture2D(0, 0);
tex.LoadImage(response.Data);
// 使用纹理...
}).Send();
}

// 方式二:直接转换
void DownloadImageDirect()
{
new HTTPRequest(new Uri("http://yourserver.com/path/to/image.png"),
(request, response) =>
{
Texture2D tex = response.DataAsTexture2D;
// 使用纹理...
}).Send();
}

五、协程支持

1
2
3
4
5
6
7
8
9
IEnumerator CoroutineRequest()
{
HTTPRequest request = new HTTPRequest(new Uri("http://server.com"));
request.Send();

yield return StartCoroutine(request);

Debug.Log("Request finished! Downloaded Data: " + request.Response.DataAsText);
}

⚠️ 注意:一般不推荐使用协程方式,建议使用回调。


六、高级配置

6.1 请求属性

属性 类型 默认值 说明
MethodType HTTPMethods Get 请求方法
IsKeepAlive bool true 是否保持 TCP 连接
DisableCache bool false 是否禁用缓存
ConnectTimeout TimeSpan 20秒 连接超时时间
Timeout TimeSpan 60秒 请求超时时间
Priority int 0 请求优先级

6.2 封装示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void RequestAsync(string url, Action<int, string> callback)
{
HTTPRequest req = new HTTPRequest(
new Uri(url),
HTTPMethods.Get,
(originalRequest, response) =>
{
if (originalRequest.State == HTTPRequestStates.Finished)
{
callback((int)originalRequest.State, response.DataAsText);
}
else
{
callback((int)originalRequest.State, "");
}
}
);

req.IsKeepAlive = false;
req.DisableCache = true;
req.Send();
}

七、身份验证

7.1 Basic 和 Digest 验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using BestHTTP.Authentication;

void AuthenticatedRequest()
{
var request = new HTTPRequest(
new Uri("http://yourserver.org/auth-path"),
(req, resp) =>
{
if (resp.StatusCode != 401)
Debug.Log("Authenticated");
else
Debug.Log("NOT Authenticated");

Debug.Log(resp.DataAsText);
}
);

request.Credentials = new Credentials("username", "password");
request.Send();
}

八、流式下载 (Download Streaming)

8.1 流式下载配置

属性 说明
UseStreaming 启用流式下载
StreamFragmentSize 内存缓冲区大小(字节)
DisableCache 禁用缓存(建议大文件时禁用)

8.2 流式下载示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void DownloadLargeFile()
{
var request = new HTTPRequest(
new Uri("http://yourserver.com/bigfile"),
(req, resp) =>
{
// 获取下载的数据片段
List<byte[]> fragments = resp.GetStreamedFragments();

// 写入文件
using (FileStream fs = new FileStream("pathToSave", FileMode.Append))
{
foreach (byte[] data in fragments)
fs.Write(data, 0, data.Length);
}

// 检查是否完成
if (resp.IsStreamingFinished)
Debug.Log("Download finished!");
}
);

request.UseStreaming = true;
request.StreamFragmentSize = 1 * 1024 * 1024; // 1 MB
request.DisableCache = true;
request.Send();
}

8.3 流式下载要点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────────────────┐
│ 流式下载流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. UseStreaming = true │
│ └── 启用流式下载,回调会被多次调用 │
│ │
│ 2. StreamFragmentSize 设置 │
│ └── 控制内存缓冲区大小,达到此大小时触发回调 │
│ │
│ 3. 回调调用时机 │
│ ├── 每下载 StreamFragmentSize 字节时触发 │
│ └── 下载完成时(IsStreamingFinished = true)再次触发 │
│ │
│ 4. GetStreamedFragments() │
│ └── 获取本次下载的数据片段,调用后内部缓冲区被清空 │
│ │
└─────────────────────────────────────────────────────────────────────────┘

九、下载进度

9.1 进度回调

1
2
3
4
5
6
7
8
9
10
11
12
void DownloadWithProgress()
{
var request = new HTTPRequest(new Uri(address), OnFinished);
request.OnProgress = OnDownloadProgress;
request.Send();
}

void OnDownloadProgress(HTTPRequest request, int downloaded, int length)
{
float progressPercent = (downloaded / (float)length) * 100.0f;
Debug.Log($"Downloaded: {progressPercent:F2}%");
}

十、流式上传 (Upload Streaming)

10.1 上传流

1
2
3
4
5
6
7
8
9
10
11
void UploadFile()
{
var request = new HTTPRequest(
new Uri(address),
HTTPMethods.Post,
OnUploadFinished
);

request.UploadStream = new FileStream("File_To_Upload", FileMode.Open);
request.Send();
}

10.2 上传进度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void UploadWithProgress()
{
var request = new HTTPRequest(
new Uri(address),
HTTPMethods.Post,
OnFinished
);

request.RawData = Encoding.UTF8.GetBytes("Field Value");
request.OnUploadProgress = OnUploadProgress;
request.Send();
}

void OnUploadProgress(HTTPRequest request, long uploaded, long length)
{
float progressPercent = (uploaded / (float)length) * 100.0f;
Debug.Log($"Uploaded: {progressPercent:F2}%");
}

十一、缓存机制

11.1 缓存说明

基于 HTTP/1.1 RFC,使用 Expires 头来存储和验证响应:

特性 说明
自动工作 缓存机制在后台自动工作
离线可用 有有效缓存时无需联网
节省带宽 直接使用本地缓存

11.2 缓存管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using BestHTTP.Caching;

// 清除整个缓存(在单独线程执行)
HTTPCacheService.BeginClear();

// 维护缓存(删除过期条目,控制缓存大小)
HTTPCacheService.BeginMaintainence(new HTTPCacheMaintananceParams(
TimeSpan.FromDays(14), // 删除14天未访问的条目
50 * 1024 * 1024 // 最大缓存大小:50MB
));

// 获取缓存信息
long cacheSize = HTTPCacheService.GetCacheSize(); // 字节
int entryCount = HTTPCacheService.GetCacheEntryCount(); // 条目数
float avgSize = cacheSize / (float)entryCount; // 平均条目大小

十二、Cookie 管理

方式 说明
HTTPRequest.IsCookiesEnabled 单个请求的 Cookie 开关
HTTPManager.IsCookiesEnabled 全局 Cookie 开关
CookieJar.Clear() 清空 Cookie Jar
1
2
3
var request = new HTTPRequest(new Uri(address), OnFinished);
request.Cookies.Add(new Cookie("Name", "Value"));
request.Send();

十三、其他功能

13.1 代理设置

1
2
3
4
5
// 单个请求
request.Proxy = new HTTPProxy(new Uri("http://localhost:3128"));

// 全局代理
HTTPManager.Proxy = new HTTPProxy(new Uri("http://proxy.example.com:8080"));

13.2 终止请求

1
2
3
4
5
request = new HTTPRequest(new Uri("http://yourserver.com/bigfile"), callback);
request.Send();

// 稍后终止
request.Abort(); // 回调将被调用,response 为 null

13.3 超时设置

1
2
3
4
5
6
7
8
9
var request = new HTTPRequest(new Uri("http://yourserver.com/"), callback);

// 连接超时(默认20秒)
request.ConnectTimeout = TimeSpan.FromSeconds(2);

// 请求超时(默认60秒)
request.Timeout = TimeSpan.FromSeconds(10);

request.Send();

十四、请求状态

14.1 状态列表

状态 说明 回调
Initial 初始状态 ❌ 不调用
Queued 在队列中等待 ❌ 不调用
Processing 处理中 ❌ 不调用
Finished 成功完成 ✅ 有效响应
Error 发生错误 ❌ null 响应
Aborted 被中止 ❌ null 响应
ConnectionTimedOut 连接超时 ❌ null 响应
TimedOut 请求超时 ❌ null 响应

14.2 状态处理示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void RequestWithStateHandling()
{
string url = "http://example.com/api";

HTTPRequest request = new HTTPRequest(new Uri(url), (req, resp) =>
{
switch (req.State)
{
case HTTPRequestStates.Finished:
Debug.Log("Request Finished Successfully! " + resp.DataAsText);
break;

case HTTPRequestStates.Error:
Debug.LogError("Request Finished with Error! " +
(req.Exception != null ? req.Exception.Message : "No Exception"));
break;

case HTTPRequestStates.Aborted:
Debug.LogWarning("Request Aborted!");
break;

case HTTPRequestStates.ConnectionTimedOut:
Debug.LogError("Connection Timed Out!");
break;

case HTTPRequestStates.TimedOut:
Debug.LogError("Processing the request Timed Out!");
break;
}
});

request.ConnectTimeout = TimeSpan.FromMilliseconds(2); // 测试用
request.Timeout = TimeSpan.FromSeconds(5);
request.IsKeepAlive = false;
request.DisableCache = true;
request.Send();
}

十五、全局设置

15.1 HTTPManager 属性

属性 默认值 说明
MaxConnectionPerServer 4 单服务器最大连接数
KeepAliveDefaultValue true 默认保持连接
IsCachingDisabled true 默认禁用缓存
MaxConnectionIdleTime 2分钟 连接空闲超时
IsCookiesEnabled true 默认启用 Cookie
CookieJarSize 10 MB Cookie 存储大小
EnablePrivateBrowsing false 禁用磁盘 Cookie
ConnectTimeout 20秒 默认连接超时
RequestTimeout 60秒 默认请求超时

15.2 全局设置示例

1
2
3
// 设置全局参数
HTTPManager.MaxConnectionPerServer = 10;
HTTPManager.RequestTimeout = TimeSpan.FromSeconds(120);

十六、线程安全

16.1 线程模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌─────────────────────────────────────────────────────────────────────────┐
│ BestHTTP 线程模型 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 主线程 │ │ 工作线程池 │ │ 主线程 │ │
│ │ (Unity线程) │ │ (多线程) │ │ (Unity线程) │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ 创建请求 │───>│ 处理请求 │───>│ 回调执行 │ │
│ │ Send() │ │ 下载/上传 │ │ 用户回调 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ • 共享资源(缓存、Cookie 等)都是线程安全的 │
│ • 回调函数在主线程执行,无需手动同步 │
│ • 从多线程创建/发送请求也是安全的 │
│ │
└─────────────────────────────────────────────────────────────────────────┘

16.2 初始化

1
2
3
4
5
// 在 Unity 的 Awake 或 Start 中调用
void Start()
{
HTTPManager.Setup();
}

十七、总结

功能 要点
基础请求 GET/POST 等方法,使用回调处理响应
数据处理 DataAsText、DataAsTexture2D
流式下载 大文件使用 UseStreaming 避免内存溢出
进度监听 OnProgress、OnUploadProgress
缓存管理 自动缓存,可手动维护
线程安全 工作线程处理,主线程回调

💡 最佳实践

  • 大文件下载使用流式下载
  • 合理设置超时时间
  • 利用缓存减少网络请求
  • 定期维护缓存和 Cookie

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1487842110@qq.com