using System; using UnityEngine; using System.Collections.Generic; using System.Collections.Concurrent; using System.Collections; using UnityEngine.Networking; public class SystemProxy : ProxyBase { public SystemProxy() => this.opeCode = OpeCode.ope_system; /// /// [6901]请求系统推送的消息 /// /// 时间戳 /// 成功回调(无返回参数) public void Request(uint ts, Action callback) { if (SystemProxy.heartBeatTag) { Post(CmdCode.cmd_systemMessage, new object[] { ts }, callback); } else { callback.Invoke(new SystemProxyRetVo()); } } /// /// [6902]上报 /// /// 时间戳 /// 成功回调(无返回参数) [Obsolete("功能不完善,封", true)] public void ReportStatLog(string eventID, string EArgKey, string EArgValue, Action callback, Action onfail) { var player = UserProxy.Instance.player; var uid = player?.uid ?? "stat"; var zoneid = player?.zoneid ?? 1; Post(CmdCode.cmd_systemStatLogReport, uid, zoneid, new object[] { eventID, EArgKey, EArgValue }, resp => callback?.Invoke(), o => onfail?.Invoke() ); } /// /// [6903]客户端心跳包 /// /// public void Heartbeat(Action callback) { var ts = UserProxy.Instance.GetCurrentUnixTimeStamp(); Post(CmdCode.cmd_sysemHeartbeat, new object[] { }, resp => { var delay = UserProxy.Instance.GetCurrentUnixTimeStamp() - ts; callback?.Invoke((int)delay); }); } public static bool heartBeatTag = false; /// /// 心跳包引擎 /// public class HearbeatBehavor : MonoSingleton { private float ts = 0; private void FixedUpdate() { ts += Time.deltaTime; if (ts > 30) { ts = 0; if (heartBeatTag) { SystemProxy.Instance.Heartbeat(delay => { if (delay > 0) { LogHelper.LogWarning($"通讯延时大概{delay}秒"); } }); } } } public void Start() { } // } } /// /// 统计辅助类 /// class StatHelper : MonoSingleton { class EventLog { public string EventID; public string EArgKey; public string EArgValue; public string UID = "-"; public string zoneid = "0"; } // private Dictionary> statLogs = new Dictionary>(); private ConcurrentQueue statLogs = new ConcurrentQueue(); /// /// 添加自定义事件 /// /// 事件ID /// 事件参数-key /// 事件参数-value public void AddEvent(string eventID, string EArgKey, string EArgValue) { var e = new EventLog() { EventID = eventID, EArgKey = EArgKey, EArgValue = EArgValue }; if (null != UserProxy.Instance.player) { e.UID = UserProxy.Instance.player.uid; e.zoneid = UserProxy.Instance.player.zoneid.ToString(); } statLogs.Enqueue(e); } private static int retryTimes = 0; private void Update() { if (statLogs.TryDequeue(out var item) && retryTimes < 3) { var url = Config_URL.Server_URL + "service_call/InquireApi/ReportStatLog.php"; var li = new List>(); li.Add(new KeyValuePair(nameof(item.EventID), item.EventID)); li.Add(new KeyValuePair(nameof(item.EArgKey), item.EArgKey)); li.Add(new KeyValuePair(nameof(item.EArgValue), item.EArgValue)); li.Add(new KeyValuePair(nameof(item.UID), item.UID)); li.Add(new KeyValuePair(nameof(item.zoneid), item.zoneid)); HttpHelper.Instance.Post(url, li, str => { // 成功 }, err => { // 失败 retryTimes++; statLogs.Enqueue(item); // 再重新发一次好了 }); } } /// /// HTTP辅助类 /// public class HttpHelper : MonoSingleton { public void Get(string url, Action OnResult, Action OnErr) { StartCoroutine(GetRequest(url, OnResult, OnErr)); } public void Post(string url, List> paras, Action OnResult, Action OnErr) { // CoroutineWrapper.Instance.EXEDelayFrames(); StartCoroutine(PostRequest(url, paras, OnResult, OnErr)); } #region ' 网络下载功能 ' // todo: 这里考虑增设cache设计,扩展下载和缓存功能. // 对于这种资源没必要每次都完整下载,这样多浪费啊,都是钱啊. // -by gwang 2017年1月20日 16:41:17 // 经验证: 在WWW中加入header if-modified-since字段可以得倒304(Nginx服务器,资源为txt类型) // 后续需要做的是一个文件管理系统,管理本地缓存文件的时间戳. // 当调用下载的时候,先检查缓存中的文件,拿到本地时间戳(FileInfo.LastWriteTimeUtc.ToString("r")),然后请求服务器, // 这样,虽然每次都请求了,但是不必每次都下发完整的文件,如果没有更新的情况下,只需返回304即可. #endregion // #region 私有方法 IEnumerator GetRequest(string url, Action OnResult, Action OnErr) { using (UnityWebRequest webRequest = UnityWebRequest.Get(url)) { yield return webRequest.SendWebRequest(); if (!string.IsNullOrEmpty(webRequest.error)) { OnErr?.Invoke(webRequest.error); } else { OnResult?.Invoke(webRequest.downloadHandler.text); } } } /// IEnumerator PostRequest(string url, List> paras, Action OnResult, Action OnErr) { WWWForm form = new WWWForm(); paras.ForEach(kv => form.AddField(kv.Key, kv.Value)); // 压入参数 using (UnityWebRequest webRequest = UnityWebRequest.Post(url, form)) { yield return webRequest.SendWebRequest(); if (!string.IsNullOrEmpty(webRequest.error)) { OnErr?.Invoke(webRequest.error); } else { OnResult?.Invoke(webRequest.downloadHandler.text); } } } #endregion } }