18 KiB
18 KiB
#灵感/代码缓存
SessionCache
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<string, object> event_properties;
}
[Serializable]
public class EventData
{
public string uuid;
public string event_name;
public long event_timestamp;
public string public_properties;
public Dictionary<string, object> event_properties;
}
public enum Session_Name
{
start_end_session, //开始/结束会话
default_session //普通会话
}
/// <summary>
/// 消息事件 缓存器
/// </summary>
public class SessionCache : Singleton<SessionCache>
{
private Dictionary<string, Dictionary<string,object>> 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<Dictionary<string,Dictionary<string,object>>>(PlayerPrefs.GetString(sessionCacheKey, ""));
}
else
{
SessionDic = new Dictionary<string, Dictionary<string,object>>();
}
}
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<string,object> start_sessionDic = new Dictionary<string, object>();
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<string,object> default_sessionDic = new Dictionary<string, object>();
SessionDic.Add("default_session", default_sessionDic);
}
break;
}
PlayerPrefs.SetString(sessionCacheKey,JsonConvert.SerializeObject(SessionDic));
PlayerPrefs.Save();
}
/// <summary>
/// 移除特定缓存数据
/// </summary>
/// <param name="event_Name">对应缓存eventName名称</param>
/// <param name="uuid"></param>
public void RemoveEventData(string event_Name, string uuid)
{
if (SessionDic.ContainsKey(event_Name) && SessionDic[event_Name].ContainsKey(uuid))
{
SessionDic[event_Name].Remove(uuid);
}
}
/// <summary>
/// 清空缓存数据
/// </summary>
public void ClearEventData()
{
foreach (KeyValuePair<string,Dictionary<string,object>> keyValuePair in SessionDic)
{
keyValuePair.Value.Clear();
}
SessionDic.Clear();
PlayerPrefs.DeleteKey(sessionCacheKey);
PlayerPrefs.Save();
}
/// <summary>
/// 发送缓存数据
/// </summary>
/// <returns></returns>
public string CacheEvent()
{
List<object> SessionList = new List<object>();
Dictionary<string, List<string>> _deleteDic = new Dictionary<string, List<string>>(); //过期需要清理的缓存数据
foreach (KeyValuePair<string,Dictionary<string,object>> keyValuePair in SessionDic)
{
switch (keyValuePair.Key)
{
case "start_end_session":
foreach (KeyValuePair<string,object> valuePair in keyValuePair.Value)
{
SessionEventData start_end_session_SessionEventData = JsonConvert.DeserializeObject<SessionEventData>(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<string> uuidList = new List<string>();
_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<string,object> valuePair in keyValuePair.Value)
{
EventData default_session_SessionEventData = JsonConvert.DeserializeObject<EventData>(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<string> uuidList = new List<string>();
_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<string,List<string>> 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
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
{
/// <summary>
/// 会话时间管理类
/// </summary>
public class SessionMgr : MonoSingleton<SessionMgr>
{
// 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<string, object> _eventDic;
private Dictionary<string, object> _userDataDic;
private string _uid = String.Empty;
private string _uuid = String.Empty;
#region 生命周期
private void Awake()
{
_uid = SystemInfo.deviceUniqueIdentifier;
}
private void OnDestroy()
{
StopNetworkRequest();
}
/// <summary>
/// 切后台 暂停游戏
/// </summary>
/// <param name="pauseStatus"></param>
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
SendEndSessionEvent();
}
else
{
CacheEvent(0);
}
}
/// <summary>
/// 退出游戏
/// </summary>
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 会话收发&业务逻辑
/// <summary>
/// 发送结束会话事件
/// </summary>
private void SendEndSessionEvent()
{
SessionEventData endData = CreateEndEvent();
ReportEvent(JsonConvert.SerializeObject(endData),false,0,endData);
}
/// <summary>
/// 初始化 发送开始会话事件
/// </summary>
/// <param name="wake"></param>
/// <param name="publicString"></param>
/// <param name="uid"></param>
/// <param name="eventDataDic"></param>
/// <param name="userDataDic"></param>
public void OnInit(bool wake,string publicString,string uid = null,Dictionary<string,object> eventDataDic = null,Dictionary<string,object> 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<string, object>();
_eventDic = new Dictionary<string, object>
{
["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);
}
/// <summary>
/// 修改事件数据
/// </summary>
/// <param name="eventDataDic"></param>
public void ChangeEventDataDic(Dictionary<string, object> eventDataDic)
{
if (eventDataDic != null)
{
Dictionary<string, object> mergedDict = _eventDic.Union(eventDataDic.Where(kvp => !_eventDic.ContainsKey(kvp.Key)))
.ToDictionary(pair => pair.Key, pair => pair.Value);
_eventDic = mergedDict;
}
}
/// <summary>
/// 修改用户数据
/// </summary>
/// <param name="userDataDic"></param>
public void ChangeUserDataDic(Dictionary<string,object> 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
}
}