123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /**
- * 功能:利用WWW类实现网络(Http)通信.
- * 版本: V1.3 -> MonoSingleton
- * 历史:
- * v1.3 调整了基类,将nethelper纳入MonoSingleton之下管理. 2017.05.10 gwang
- * v1.2 修改了数据编码协议:
- * POST, 数据先json_encode然后deflate压缩, 返回值先inflate解压再json_decode.
- * GET , 数据先json_encode然后base64_encode再附加到url之后, 返回值先base64_decode解码再json_decode.
- * 2016.4.26 gwang
- * v1.1.1 修改返回值/请求值的类型, 从JObject->ResponseVo和RequestVo. 2016.4.14 gwang
- * v1.0.1 引自明星志愿项目, 并稍作调整, 主要是配套了下ErrCode. 2016.4.11 gwang
- */
- using UnityEngine;
- using UnityEngine.Networking;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.Concurrent;
- using System.Threading;
- using System.Threading.Tasks;
- using System;
- using Newtonsoft.Json;
- using System.Text;
- /// <summary>
- /// HTTP 网络通讯辅助类
- /// </summary>
- [Obsolete("2022.9.7 已用HTTPHelper(并发通讯)替换. 此版本为串行通讯.")]
- public class NetHelper : MonoSingleton<NetHelper> // MonoBehaviour
- {
- // 目标通讯地址
- private string mHost = string.Empty;
- // 发送队列
- private ConcurrentQueue<NetPacket> mPacketQueue = new ConcurrentQueue<NetPacket>();
- // 当前网络状态
- private ENetStatus mNetStatus = ENetStatus.ENS_IDLE;
- public NetHelper()
- { //string targetUrl targetUrl;//
- mHost = Config_URL.Server_URL;
- }
- /// <summary>
- /// 提供Http Post方法
- /// </summary>
- /// <param name="ctx">传输内容</param>
- /// <param name="callback">回调函数</param>
- public void Post(int op, ReqVo ctx, int timeout, Action<RespVo> callback)
- {
- NetPacket packet = NetPacketFactory.CreatePacket();
- packet.url = mHost;
- packet.request = ctx;
- packet.handler = callback;
- packet.tsTimeout = timeout;
- mPacketQueue.Enqueue(packet);
- }
- /// <summary>
- /// 提供HTTP GET方法, 返回JSON形式
- /// </summary>
- /// <param name="url">请求地址</param>
- /// <param name="callback">回调函数</param>
- public void Get(string url, Dictionary<string, string> ctx, Action<RespVo> callback, int timeout)
- {
- NetPacket packet = NetPacketFactory.CreatePacket();
- if (null != ctx && ctx.Count > 0)
- {
- StringBuilder buffer = new StringBuilder();
- int i = 0;
- url += "?";
- foreach (KeyValuePair<String, String> kv in ctx)
- {
- buffer.AppendFormat("{0}{1}={2}", i > 0 ? "&" : "", kv.Key, kv.Value);
- ++i;
- }
- string paras = buffer.ToString();
- url += CSharpUtil.Base64Util.Encode(paras);
- }
- packet.url = url;
- packet.handler = callback;
- packet.tsTimeout = timeout;
- mPacketQueue.Enqueue(packet);
- }
- private void Start()
- {
- DontDestroyOnLoad(this);
- }
- /// <summary>
- /// 帧周期更新
- /// </summary>
- private void Update()
- {
- if (mNetStatus == ENetStatus.ENS_BUSY)
- return;
- if (mPacketQueue.TryDequeue(out NetPacket packet))
- {
- mNetStatus = ENetStatus.ENS_BUSY;
- StartCoroutine(Request(packet));
- }
- }
- private void RaiseResult(NetPacket packet)
- {
- mNetStatus = ENetStatus.ENS_IDLE;
- if (packet.errid == 0)
- {
- packet.handler(packet.response);
- }
- else
- {
- UI_CueDialog.Instance().Open("连接不到游戏服务器, 请检查网络.", "网络故障", E_DialogType.OneButton, ExitGame);
- throw new UnityException("网络模块故障, 需要应用上层逻辑处理或重置网络.");
- }
- }
- /// <summary>
- /// 网络请求
- /// </summary>
- /// <returns></returns>
- private IEnumerator Request(NetPacket packet)
- {
- WWW www = null;
- packet.tsRequest = DateTime.Now;
- DateTime maxTs = packet.tsRequest.AddSeconds(packet.tsTimeout);
- if (packet.request == null) // 处理Get请求
- {
- www = new WWW(packet.url);
- }
- else // 处理Post请求
- {
- string ctx = JsonConvert.SerializeObject(packet.request); // 序列化
- if (GlobalConfig.GAME_COMM_DEBUG)
- {
- var msg = ctx.Length > 1024 ? $"{ctx[..150]}...{ctx[^30..]}" : ctx;
- LogHelper.Log($"[SEND:]{msg}");
- }
- // 编码
- byte[] data = CSharpUtil.CompressUtil.Deflate(GlobalConfig.Encoding.GetBytes(ctx));
- www = new WWW(packet.url, data);
- }
- if (null == www || www.error != null)
- {
- LogHelper.Log("www error:" + www.error);
- packet.errid = ErrCode.net_connectno;
- packet.error = www.error;
- this.RaiseResult(packet);
- yield break;
- }
- // 超时检测
- while (false == www.isDone)
- {
- TimeSpan span = DateTime.Now - maxTs;
- if (span.TotalMilliseconds < 0)
- {
- yield return null;
- }
- else
- {
- packet.errid = ErrCode.net_timeout;
- packet.error = "timeout";
- this.RaiseResult(packet);
- yield break;
- }
- }
- // 网络错误检测
- if (www.error != null || www.text == null)
- {
- packet.errid = ErrCode.net_other;
- packet.error = www.error;
- this.RaiseResult(packet);
- yield break;
- }
- packet.tsResp = DateTime.Now;
- // 解码
- string decode = CSharpUtil.CompressUtil.InFlate(www.bytes, GlobalConfig.Encoding);
- if (null == decode || decode == "null")
- {
- packet.errid = ErrCode.net_decode;
- packet.error = "decodeerror";
- this.RaiseResult(packet);
- yield break;
- }
- if (GlobalConfig.GAME_COMM_DEBUG)
- {
- string format = decode; // decode.Replace("\\r\\n", "");
- var msg = format.Length > 1024 ? format[..150] + $"...({format.Length/1024:.0kb})..." + format[^30..] : format; // 约简日志长度
- var sp = (packet.tsResp - packet.tsRequest).TotalMilliseconds; // 计算往返耗时
- LogHelper.Log($"[RECV:]({sp:.00}ms){msg}");
- }
- packet.response = JsonConvert.DeserializeObject<RespVo>(decode); // 反序列化
- this.RaiseResult(packet);
- }
- /// <summary>
- /// 退出游戏
- /// </summary>
- private void ExitGame()
- {
- Application.Quit();
- }
- }
-
|