基本思路
HttpManager(管理器)
HttpPack(数据包)
HttpClient(核心逻辑)
总结
基础框架的主体分为两个部分HttpManager(提供外部接口)和HttpClient(处理内部核心机制)
主要负责提供业务层访问的接口如Get,Post。以及获取返回结果的接口。
// HttpClient对象
private HttpClient _httpClient = new HttpClient();
// 供业务层调用的Get接口
public void HttpGet(int key, string url, bool encry, string param = null)
{
// 处理参数
...
// 调用HttpClient注册发送请求到发送队列中
_httpClient.AddHttpReq(...);
}
// 供业务层调用的Post接口
public void HttpPost(int key, string url, bool encry, string param = null)
{
// 处理参数
...
// 调用HttpClient注册发送请求到发送队列中
_httpClient.AddHttpReq(...);
}
// 获取返回数据的接口
public bool TryGetResPonse(ref int key, ref int code, ref string data)
{
// 从接受队列中取得一条数据,将获取的信息返回回去
_httpClient.TryGetResponse(out pack)
...
}
key:当前Http请求的一个事件id,发送的时候传入,接受的时候返回。主要用于在接受了消息之后做事件派发,供业务层监听并处理Http请求回调。
url:http请求地址
encry:是否是加密消息
param:参数
code:http请求返回的状态码
data:http请求返回的内容
获取返回数据的接口参数加了一个ref是为了和lua做通信
这里用一个HttpPack来封装Http请求所需要用到的所有数据,发送队列和接受队列力保存的就是HttpPack
public class HttpPack
{
// 协议类型(Get 或者 Post)
public HttpType type;
// 请求返回的状态码
public int code;
// 是否为加密请求
public bool encry;
// 重试次数
public int tryNum;
// 事件id
public int key;
// 请求地址
public string url;
// 请求参数
public string param;
// 返回的数据
public string response;
}
httpclient主要封装.net库力的webrequest来提供符合自己需求的Post和Get接口
开启一个线程来取得发送队列的数据并执行Get或Post请求,处理好之后插入到接受队列中
存储和处理发送队列以及接受队列,发送队列和接受队列会经过一层封装使得其满足多线程的使用(代码里的BlockQueue就是封装过的队列)
// 发送任务线程
private Thread _sendTask;
// 发送队列
private BlockQueue _sendList = new BlockQueue(10);
// 接受队列
private BlockQueue _receiveList = new BlockQueue(10);
#region 外部接口
// 尝试从接受队列中取得一条数据并返回
public bool TryGetResponse(out HttpPack pack)
{
if (_receiveList.count > 0)
{
pack = _receiveList.Dequeue();
return true;
}
else
{
pack = null;
return false;
}
}
// 注册一个请求到发送队列中
public void AddHttpReq(int key, HttpType type, string url, bool encry, string param = null)
{
HttpPack pack = HttpPack.GetPooled();
// 将参数设置到HttpPack中然后插入到发送队列里
_sendList.Enqueue(pack);
}
#endregion
// 构造函数中启动一个发送任务线程
public HttpClient()
{
_sendTask = StartDaemonThread(StartSend);
}
private static Thread StartDaemonThread(ThreadStart threadMethod)
{
Thread thread = new Thread(threadMethod);
thread.IsBackground = true;
thread.Start();
return thread;
}
private void StartSend()
{
while (true)
{
// 从发送队列中取得一个HttpPack分类型调用请求
if (_sendList.count > 0)
{
HttpPack pack = _sendList.Dequeue();
switch (pack.type)
{
case HttpType.Get:
{
Get(ref pack, pack.url, pack.encry);
HandleRecive(ref pack);
return;
}
case HttpType.Post:
{
Post(ref pack, pack.url, pack.param, pack.encry);
HandleRecive(ref pack);
return;
}
}
}
}
}
// 封装的Get请求
private void Get(ref HttpPack pack, string url, bool encry, int timeout = 2000, Encoding encode = null)
{
// 处理参数调用.net库发起访问
...
// 处理加密
...
// 将结果插入到HttpPack中
...
}
// 封装的Post请求
private void Post(ref HttpPack pack, string url, string postdata, bool encry, int timeout = 2000, Encoding encode = null)
{
// 处理参数调用.net库发起访问
...
// 处理加密
...
// 将结果插入到HttpPack中
...
}
// 处理接收
private void HandleRecive(ref HttpPack pack)
{
// 异常时重试
if (pack.code != 200 && pack.tryNum > 0)
{
pack.tryNum--;
_sendList.Enqueue(pack);
}
// 正常接受或者重试超过次数则将请求注册到接受队列
else
{
_receiveList.Enqueue(pack);
}
}
这个Http框架主要有三个核心的板块HttpManager、HttpClient、HttpPack
Httpmanager提供业务层的访问并且管理HttpClient。
HttpClient主要封装了对多线程,以及发送接受队列的处理方法,封装了.Net库的Get和Post请求。
HttpPack贯穿于整个处理的生命周期,用于保存一个Http请求处理链上用到的所有必要数据。
完整版的代码请到《Unity游戏开发 基于多线程的Http网络框架完整篇》这里获取。