This commit is contained in:
2026-08-01 15:27:12 +08:00
parent f9b60ea26e
commit dddcbbfbfa
5 changed files with 72 additions and 14 deletions
+5 -5
View File
@@ -249,7 +249,7 @@ namespace Assets.MyGame.Scripts.Net
var json = req.downloadHandler.text;
var res = JsonConvert.DeserializeObject<APIResponse<T>>(json);
#if UNITY_EDITOR
Debug.Log("url----" + url+"--"+ "Json-"+json+"res--"+JsonConvert.SerializeObject(res));
Debug.Log("url----" + url + "--" + "Json-" + json + "res--" + JsonConvert.SerializeObject(res));
#endif
Debug.Log("url----" + url + "--" + "Json-" + json + "res--" + JsonConvert.SerializeObject(res));
@@ -313,9 +313,9 @@ namespace Assets.MyGame.Scripts.Net
var res = JsonConvert.DeserializeObject<APIResponse<T>>(json);
#if UNITY_EDITOR
Debug.Log("url----" + url + "--" + "Json-" + json + "res--" + JsonConvert.SerializeObject(res));
#else
Debug.Log("url----" + url + "--" + "Json-" + json + "res--" + JsonConvert.SerializeObject(res));
#endif
Debug.Log("url----" + url + "--" + "Json-" + json + "res--" + JsonConvert.SerializeObject(res));
// 自动保存 token
if (typeof(T) == typeof(UserToken))
@@ -383,8 +383,8 @@ namespace Assets.MyGame.Scripts.Net
}
public static void Log(string json)
{
#if UNITY_EDITOR
Debug.Log(json);
#if UNITY_EDITOR
Debug.Log(json);
#endif
}
+47 -2
View File
@@ -27,6 +27,11 @@ namespace Assets.MyGame.Scripts.Net
private readonly HashSet<SocketType> handshakeCompleted = new();
private readonly HashSet<SocketType> reconnecting = new();
private readonly HashSet<SocketType> manualClosing = new();
/// <summary>登出标志:true 时所有 socket 关闭后都不触发自动重连。
/// Logout 开始时设 true,切回登录界面后设 false,避免关连接时误触发重连访问已 null 的 user。</summary>
public bool isLoggingOut = false;
/// <summary>每个 socketType 正在运行的重连协程引用,用于主动 StopCoroutine</summary>
private readonly Dictionary<SocketType, Coroutine> reconnectCoroutines = new();
private float nextHeartbeatTime;
private const float HeartbeatIntervalSeconds = 20f;
#if ENABLE_LOG_FILE
@@ -154,6 +159,11 @@ namespace Assets.MyGame.Scripts.Net
sockets.Remove(type);
if (manualClosing.Remove(type))
return;
// ⭐ 登出中或未登录:不触发自动重连。
// isLoggingOut 可能因 ws.Close 异步导致 OnClosed 触发时已重置,
// 所以同时检查 user==null 做双重保险(登出后 user 必为 null)
if (isLoggingOut || GameManager.Instance.user == null)
return;
// 自动重连
switch (type)
@@ -256,7 +266,7 @@ namespace Assets.MyGame.Scripts.Net
{
if (sockets.TryGetValue(type, out var ws))
{
manualClosing.Add(type);
//manualClosing.Add(type);
handshakeCompleted.Remove(type);
ws.Close(WebSocketStatusCodes.NormalClosure, "正常关闭"); // 或者 CloseStatusCode.Normal
//ws.Close();
@@ -269,6 +279,9 @@ namespace Assets.MyGame.Scripts.Net
/// </summary>
public void CloseAll()
{
// ⭐ 先停止所有重连协程:socket 因 ClosedAbnormally 关闭时已从 sockets 移除,
// CloseAll 遍历 sockets.Keys 会漏掉它,导致重连协程继续运行。这里统一停止。
StopAllReconnects();
foreach (var type in new List<SocketType>(sockets.Keys))
{
Close(type);
@@ -282,7 +295,23 @@ namespace Assets.MyGame.Scripts.Net
{
if (!reconnecting.Add(type))
return;
StartCoroutine(Reconnect(type, action));
var co = StartCoroutine(Reconnect(type, action));
reconnectCoroutines[type] = co;
}
/// <summary>
/// 主动停止所有正在等待的重连协程并清空状态。
/// 用于 Logout 时彻底取消所有待重连任务,不依赖 isLoggingOut 时序。
/// </summary>
public void StopAllReconnects()
{
foreach (var kv in reconnectCoroutines)
{
if (kv.Value != null)
StopCoroutine(kv.Value);
}
reconnectCoroutines.Clear();
reconnecting.Clear();
}
private System.Collections.IEnumerator Reconnect(SocketType type, Action action = null)
@@ -296,9 +325,18 @@ namespace Assets.MyGame.Scripts.Net
if (manualClosing.Contains(type))
{
reconnecting.Remove(type);
reconnectCoroutines.Remove(type);
yield break;
}
// ⭐ 登出中或未登录:取消已排队等待的重连
if (isLoggingOut || GameManager.Instance.user == null)
{
reconnecting.Remove(type);
reconnectCoroutines.Remove(type);
yield break;
}
reconnectCoroutines.Remove(type);
socketUrls.TryGetValue(type, out var url);
Connect(type, url, action);
}
@@ -311,6 +349,12 @@ namespace Assets.MyGame.Scripts.Net
switch (type)
{
case SocketType.login:
// ⭐ 防御:登出后 user 可能为 null,避免 NRE
if (GameManager.Instance.user == null || string.IsNullOrEmpty(GameManager.Instance.user.id))
{
Debug.LogWarning("[WebSocket] login 握手完成但 user 为 null,跳过 Bind(可能登出中)");
return;
}
WebSocketSendList.Bind(GameManager.Instance.user.id);
break;
case SocketType.chess:
@@ -330,6 +374,7 @@ namespace Assets.MyGame.Scripts.Net
/// </summary>
private void OnDestroy()
{
StopAllReconnects();
foreach (var type in new List<SocketType>(sockets.Keys))
manualClosing.Add(type);
foreach (var ws in new List<WebSocket>(sockets.Values))