obsidian/笔记文件/2.笔记/单个缓存器.md
2025-03-26 00:02:56 +08:00

274 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#灵感/代码缓存
## 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;
using Random = System.Random;
namespace CGBU_SDK
{
[Serializable]
public class SessionEventData
{
public string event_name;
public long event_timestamp;
public string public_properties;
public Dictionary<string, object> event_properties;
}
/// <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 List<SessionEventData> sessionEventDataList; //临时缓存数据
private int ListCount = 10; //临时缓存数据大小
#region 生命周期
private void Awake()
{ _uid = SystemInfo.deviceUniqueIdentifier;
sessionEventDataList = new List<SessionEventData>(ListCount); //和晨辉沟通设置最大数量为10
}
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());
// SendEndSessionEvent();
}
private SessionEventData CreateEndEvent()
{ _endEventTimestamp = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
SessionEventData _sessionEndEventData = new SessionEventData
{
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 (!wake)
{ Destroy(gameObject);
return; }
SessionCache.Instance.OnInit();
_uid = uid != null ? uid : _uid;
_publicString = publicString;
_startEventTimestamp = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
_sessionId = _uid + _startEventTimestamp + GenerateRandomString(10);
_userDataDic = new Dictionary<string, object>();
_eventDic = new Dictionary<string, object>
{
["session_id"] = _sessionId,
["session_dur"] = 0,
["user_properties"] = _userDataDic
};
SessionEventData _sessionStartEventData = new SessionEventData
{
event_name = StartSession,
event_timestamp = _startEventTimestamp,
public_properties = _publicString,
event_properties = _eventDic
};
ChangeEventDataDic(eventDataDic);
ChangeUserDataDic(userDataDic);
if (PlayerPrefs.HasKey(sessionCachePrefsKey))
{ sessionEventDataList =
JsonConvert.DeserializeObject<List<SessionEventData>>(PlayerPrefs.GetString(sessionCachePrefsKey,
""));
}
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;
}
/// <summary>
/// 生成随机数字字符串
/// </summary>
/// <param name="length"></param> /// <returns></returns> private string GenerateRandomString(int length)
{ const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var random = new Random();
var stringChars = new char[length];
for (int i = 0; i < stringChars.Length; i++)
{ stringChars[i] = chars[random.Next(chars.Length)];
}
var randomString = new string(stringChars);
return randomString;
}
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;
Debug.Log("SendData:"+eventDataStr);
// 发送POST请求
// using (UnityWebRequest www = new UnityWebRequest("https://7b6zvje56lpbtmjuzwulj36qoi0hikbc.lambda-url.us-east-1.on.aws?appid=" + AnalyseAppId, "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);
// CacheEvent(jsonData,isReSend,reSendCount);
}
else
{
Debug.Log("SuccessData:"+eventDataStr);
// 获取服务器响应的文本内容
string responseText = www.downloadHandler.text;
// 输出服务器响应内容
Debug.Log("Server Response: " + responseText);
if (isReSend)
{ sessionEventDataList.Clear();
PlayerPrefs.DeleteKey(sessionCachePrefsKey);
PlayerPrefs.Save();
}
else //如果不是重发,说明第一次就发送成功了
{
if (eventData != null && sessionEventDataList.Contains(eventData))
{ Debug.Log("SuccessData_1:"+eventDataStr);
sessionEventDataList.Remove(eventData);
}
} }
if (www.isNetworkError || www.isHttpError)
{ Debug.LogError("Error: " + www.error);
Debug.Log("ErrorData_2:"+eventDataStr);
}
CacheEvent(reSendCount);
}
} private void CacheEvent(int reSendCount = 0)
{ if (reSendCount >= 1)
{ return;
}
if (sessionEventDataList.Count >0)
{ string ListStr = JsonConvert.SerializeObject(sessionEventDataList);
reSendCount += 1;
ReportEvent(ListStr,true,reSendCount);
}
}
private void AddToList(SessionEventData sessionEventData)
{ if (sessionEventDataList.Count >= ListCount)
{ sessionEventDataList.RemoveAt(0);
}
sessionEventDataList.Add(sessionEventData);
PlayerPrefs.SetString(sessionCachePrefsKey,JsonConvert.SerializeObject(sessionEventDataList));
PlayerPrefs.Save();
}
#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
}
}
```