#灵感/代码缓存 ## SessionCache ``` cs using System; using System.Collections.Generic; using HTFramework.Utility; using Newtonsoft.Json; using UnityEngine; namespace DefaultNamespace { [Serializable] public class SessionEventData { public string uuid; public string event_name; public long event_timestamp; public string public_properties; public Dictionary event_properties; } [Serializable] public class EventData { public string uuid; public string event_name; public long event_timestamp; public string public_properties; public Dictionary event_properties; } public enum Session_Name { start_end_session, //开始/结束会话 default_session //普通会话 } /// /// 消息事件 缓存器 /// public class SessionCache : Singleton { private Dictionary> SessionDic; private string sessionCacheKey = "sessionCacheKey"; private string _publicString = String.Empty; private int _deleteDay; //延迟几天删除 public void OnInit(string publicString,int day) { // if (PlayerPrefs.HasKey(sessionCacheKey)) // { // PlayerPrefs.DeleteKey(sessionCacheKey); // PlayerPrefs.Save(); // } // return; _publicString = publicString; _deleteDay = day; InitData(); } private void InitData() { if (PlayerPrefs.HasKey(sessionCacheKey)) { SessionDic = JsonConvert.DeserializeObject>>(PlayerPrefs.GetString(sessionCacheKey, "")); } else { SessionDic = new Dictionary>(); } } public void AddEvetData(Session_Name event_Name,object eventData) { switch (event_Name) { case Session_Name.start_end_session: SessionEventData start_end_session = eventData as SessionEventData; start_end_session.public_properties = String.Empty; if (!SessionDic.ContainsKey("start_end_session")) { Dictionary start_sessionDic = new Dictionary(); SessionDic.Add("start_end_session", start_sessionDic); } SessionDic["start_end_session"].Add(start_end_session.uuid,JsonConvert.SerializeObject(start_end_session)); break; case Session_Name.default_session: EventData default_session = eventData as EventData; default_session.public_properties = String.Empty; if (!SessionDic.ContainsKey("default_session")) { Dictionary default_sessionDic = new Dictionary(); SessionDic.Add("default_session", default_sessionDic); } break; } PlayerPrefs.SetString(sessionCacheKey,JsonConvert.SerializeObject(SessionDic)); PlayerPrefs.Save(); } /// /// 移除特定缓存数据 /// /// 对应缓存eventName名称 /// public void RemoveEventData(string event_Name, string uuid) { if (SessionDic.ContainsKey(event_Name) && SessionDic[event_Name].ContainsKey(uuid)) { SessionDic[event_Name].Remove(uuid); } } /// /// 清空缓存数据 /// public void ClearEventData() { foreach (KeyValuePair> keyValuePair in SessionDic) { keyValuePair.Value.Clear(); } SessionDic.Clear(); PlayerPrefs.DeleteKey(sessionCacheKey); PlayerPrefs.Save(); } /// /// 发送缓存数据 /// /// public string CacheEvent() { List SessionList = new List(); Dictionary> _deleteDic = new Dictionary>(); //过期需要清理的缓存数据 foreach (KeyValuePair> keyValuePair in SessionDic) { switch (keyValuePair.Key) { case "start_end_session": foreach (KeyValuePair valuePair in keyValuePair.Value) { SessionEventData start_end_session_SessionEventData = JsonConvert.DeserializeObject(valuePair.Value.ToString()); start_end_session_SessionEventData.public_properties = _publicString; if (GetDeleyTime(start_end_session_SessionEventData.event_timestamp)) { if (!_deleteDic.ContainsKey(start_end_session_SessionEventData.event_name)) { List uuidList = new List(); _deleteDic.Add(start_end_session_SessionEventData.event_name,uuidList); } _deleteDic[start_end_session_SessionEventData.event_name].Add(start_end_session_SessionEventData.uuid); } SessionList.Add(start_end_session_SessionEventData); } break; case "default_session": foreach (KeyValuePair valuePair in keyValuePair.Value) { EventData default_session_SessionEventData = JsonConvert.DeserializeObject(valuePair.Value.ToString()); default_session_SessionEventData.public_properties = _publicString; if (GetDeleyTime(default_session_SessionEventData.event_timestamp)) { if (!_deleteDic.ContainsKey(default_session_SessionEventData.event_name)) { List uuidList = new List(); _deleteDic.Add(default_session_SessionEventData.event_name,uuidList); } _deleteDic[default_session_SessionEventData.event_name].Add(default_session_SessionEventData.uuid); } SessionList.Add(default_session_SessionEventData); } break; } } foreach (KeyValuePair> keyValuePair in _deleteDic) { for (int i = 0; i < keyValuePair.Value.Count; i++) { SessionDic[keyValuePair.Key].Remove(keyValuePair.Value[i]); } } if (SessionList.Count <= 0) { return String.Empty; } return JsonConvert.SerializeObject(SessionList); } private bool GetDeleyTime(long t) { double time = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000 - t; if (Math.Floor(time / 86400) > _deleteDay) { return true; } return false; } } } ``` ## SessionMgr ``` cs using System; using System.Collections; using System.Collections.Generic; using System.Linq; using DefaultNamespace; using HTFramework.Utility; using UnityEngine; using Newtonsoft.Json; using UnityEngine.Networking; namespace CGBU_SDK { /// /// 会话时间管理类 /// public class SessionMgr : MonoSingleton { // private const string appId = "3f99e16c541a"; // private const string reportUrl = "https://global-receiver-ias.icongamesg.com/report/?appid=" + appId; private const string StartSession = "start_session"; private const string EndSession = "end_session"; // private const string sessionCachePrefsKey = "sessionCachePrefsKey"; private const string ReSendUrl = "&batch=1"; private string _sessionId; private string _publicString; private long _startEventTimestamp; private long _endEventTimestamp; private Dictionary _eventDic; private Dictionary _userDataDic; private string _uid = String.Empty; private string _uuid = String.Empty; #region 生命周期 private void Awake() { _uid = SystemInfo.deviceUniqueIdentifier; } private void OnDestroy() { StopNetworkRequest(); } /// /// 切后台 暂停游戏 /// /// private void OnApplicationPause(bool pauseStatus) { if (pauseStatus) { SendEndSessionEvent(); } else { CacheEvent(0); } } /// /// 退出游戏 /// private void OnApplicationQuit() { AddToList(CreateEndEvent()); } private SessionEventData CreateEndEvent() { _endEventTimestamp = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; SessionEventData _sessionEndEventData = new SessionEventData { uuid = _uuid, event_name = EndSession, event_timestamp = _endEventTimestamp, public_properties = _publicString, event_properties = _eventDic }; _sessionEndEventData.event_name = EndSession; _sessionEndEventData.event_timestamp = _endEventTimestamp; _sessionEndEventData.event_properties["session_dur"] = _endEventTimestamp - _startEventTimestamp; _sessionEndEventData.event_properties["user_properties"] = _userDataDic; return _sessionEndEventData; } #endregion #region 会话收发&业务逻辑 /// /// 发送结束会话事件 /// private void SendEndSessionEvent() { SessionEventData endData = CreateEndEvent(); ReportEvent(JsonConvert.SerializeObject(endData),false,0,endData); } /// /// 初始化 发送开始会话事件 /// /// /// /// /// /// public void OnInit(bool wake,string publicString,string uid = null,Dictionary eventDataDic = null,Dictionary userDataDic = null) { // if (PlayerPrefs.HasKey(sessionCachePrefsKey)) // { // PlayerPrefs.DeleteKey(sessionCachePrefsKey); // PlayerPrefs.Save(); // } // return; if (!wake) { Destroy(gameObject); return; } SessionCache.Instance.OnInit("",7); _uid = uid != null ? uid : _uid; _publicString = publicString; _startEventTimestamp = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; // _sessionId = _uid + _startEventTimestamp + GenerateRandomString(10); _sessionId = DateTime.Now.ToUniversalTime().Ticks.ToString(); _uuid = Guid.NewGuid() + "-" + DateTime.Now.ToUniversalTime().Ticks; _userDataDic = new Dictionary(); _eventDic = new Dictionary { ["session_id"] = _sessionId, ["session_dur"] = 0, ["user_properties"] = _userDataDic }; SessionEventData _sessionStartEventData = new SessionEventData { uuid = _uuid, event_name = StartSession, event_timestamp = _startEventTimestamp, public_properties = _publicString, event_properties = _eventDic }; ChangeEventDataDic(eventDataDic); ChangeUserDataDic(userDataDic); ReportEvent(JsonConvert.SerializeObject(_sessionStartEventData), false, 0, _sessionStartEventData); } /// /// 修改事件数据 /// /// public void ChangeEventDataDic(Dictionary eventDataDic) { if (eventDataDic != null) { Dictionary mergedDict = _eventDic.Union(eventDataDic.Where(kvp => !_eventDic.ContainsKey(kvp.Key))) .ToDictionary(pair => pair.Key, pair => pair.Value); _eventDic = mergedDict; } } /// /// 修改用户数据 /// /// public void ChangeUserDataDic(Dictionary userDataDic) { _userDataDic = userDataDic == null ? _userDataDic : userDataDic; } private void ReportEvent(string eventDataStr,bool isReSend = false,int reSendCount = 0,SessionEventData eventData = null) { if (eventData != null) { AddToList(eventData); } StartNetworkRequest(Instance.SendSessionEvent(eventDataStr,isReSend,reSendCount,eventData)); } private IEnumerator SendSessionEvent(string eventDataStr,bool isReSend = false,int reSendCount = 0,SessionEventData eventData = null) { string AnalyseAppId = isReSend == false ? "8d482dec8f6d" : "8d482dec8f6d" + ReSendUrl; // 发送POST请求 using (UnityWebRequest www = new UnityWebRequest("https://7b6zvje56lpbtmjuzwulj36qoi0hikbc.lambda-url.us-east-1.on.aws?appid=" + AnalyseAppId, "POST")) { byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(eventDataStr); www.uploadHandler = new UploadHandlerRaw(bodyRaw); www.downloadHandler = new DownloadHandlerBuffer(); www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); // 检查是否有错误发生 if (www.result != UnityWebRequest.Result.Success) { // Debug.Log("Error: " + www.error); } else { // 获取服务器响应的文本内容 // string responseText = www.downloadHandler.text; // 输出服务器响应内容 // Debug.Log("Server Response: " + responseText); if (isReSend) //如果是批量重发,就清空缓存器 { SessionCache.Instance.ClearEventData(); } else //如果不是重发,说明第一次就发送成功了,检测是否在缓存中,如果存在于缓存中,删除即可 { if (eventData != null) { SessionCache.Instance.RemoveEventData(eventData.event_name,eventData.uuid); } } } if (www.isNetworkError || www.isHttpError) { // Debug.LogError("Error: " + www.error); } CacheEvent(reSendCount); } } private void CacheEvent(int reSendCount = 0) { if (reSendCount >= 1) //只重发一次 { return; } string ListStr = SessionCache.Instance.CacheEvent(); if (ListStr != String.Empty) { reSendCount += 1; ReportEvent(ListStr,true,reSendCount); } } private void AddToList(SessionEventData sessionEventData) { SessionCache.Instance.AddEvetData(Session_Name.start_end_session,sessionEventData); } #endregion #region 协程处理 private Coroutine networkCoroutine; private void StartNetworkRequest(IEnumerator coroutine) { if (networkCoroutine == null) //检查是否已有协程在运行 { networkCoroutine = StartCoroutine(coroutine); } else { StopCoroutine(networkCoroutine); networkCoroutine = StartCoroutine(coroutine); } } private void StopNetworkRequest() { if (networkCoroutine != null) { StopCoroutine(networkCoroutine); networkCoroutine = null; } } #endregion } } ```