Unity BestHTTP 插件完全指南 - 基础篇
BestHTTP 是基于 RFC 2616 的 HTTP/1.1 实现,支持几乎所有 Unity 移动和独立平台。本文档详细介绍其基础用法和高级功能。
一、插件概述
1.1 特性
| 特性 |
说明 |
| 标准兼容 |
基于 HTTP/1.1 RFC 2616 规范实现 |
| 跨平台 |
支持几乎所有 Unity 移动和独立平台 |
| 易于使用 |
简洁的 API,强大的功能 |
| 线程安全 |
多线程处理,回调在主线程执行 |
| 丰富功能 |
支持流式下载、缓存、Cookie、代理等 |
1.2 引入命名空间
⚠️ 注意:本文档中的所有示例代码都省略了错误检查,实际使用时请务必添加空值检查。
二、快速入门
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); } }
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(); }
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() { new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Head, callback).Send();
new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Put, callback).Send();
new HTTPRequest(new Uri("http://server.com/path"), HTTPMethods.Delete, callback).Send();
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; 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), 50 * 1024 * 1024 ));
long cacheSize = HTTPCacheService.GetCacheSize(); int entryCount = HTTPCacheService.GetCacheEntryCount(); float avgSize = cacheSize / (float)entryCount;
|
十二、Cookie 管理
12.1 Cookie 控制
| 方式 |
说明 |
HTTPRequest.IsCookiesEnabled |
单个请求的 Cookie 开关 |
HTTPManager.IsCookiesEnabled |
全局 Cookie 开关 |
CookieJar.Clear() |
清空 Cookie Jar |
12.2 手动添加 Cookie
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();
|
13.3 超时设置
1 2 3 4 5 6 7 8 9
| var request = new HTTPRequest(new Uri("http://yourserver.com/"), callback);
request.ConnectTimeout = TimeSpan.FromSeconds(2);
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
| void Start() { HTTPManager.Setup(); }
|
十七、总结
| 功能 |
要点 |
| 基础请求 |
GET/POST 等方法,使用回调处理响应 |
| 数据处理 |
DataAsText、DataAsTexture2D |
| 流式下载 |
大文件使用 UseStreaming 避免内存溢出 |
| 进度监听 |
OnProgress、OnUploadProgress |
| 缓存管理 |
自动缓存,可手动维护 |
| 线程安全 |
工作线程处理,主线程回调 |
💡 最佳实践:
- 大文件下载使用流式下载
- 合理设置超时时间
- 利用缓存减少网络请求
- 定期维护缓存和 Cookie
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1487842110@qq.com