using System; using System.Collections; using System.Threading.Tasks; using UnityEngine; //客户端断线重连 public class ClientReconnectingState : ClientConnectingState { Coroutine m_ReconnectCoroutine; int curAttempts; //断线重连间隔 const float TimeBetweenAttempts = 5; public override void Enter() { curAttempts = 0; m_ReconnectCoroutine = m_ConnectionManager.NetworkManager.StartCoroutine(ReconnectCoroutine()); //通知UI,转Loading MessageCenter.SendMessage(EventDefine.ConnectStatusEvent, ConnectStatus.Reconnecting); //MessageCenter.SendMessage(EventDefine.ClientReConnectionEvent, new ReconnectMessage(curAttempts, m_ConnectionManager.ReconnectAttempts)); } public override void Exit() { if(m_ReconnectCoroutine != null) { m_ConnectionManager.NetworkManager.StopCoroutine(m_ReconnectCoroutine); m_ReconnectCoroutine = null; } //触发消息 //MessageCenter.SendMessage(EventDefine.ClientReConnectionEvent, new ReconnectMessage(curAttempts, m_ConnectionManager.ReconnectAttempts)); } //连接成功,跳转到ClientConnectedState public override void OnClientConnected(ulong clientId) { MessageCenter.SendMessage(EventDefine.ConnectStatusEvent, ConnectStatus.Success); m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnected); } //服务端被动断开连接 public override void OnClientDisconnect(ulong _) { if(curAttempts < m_ConnectionManager.ReconnectAttempts) { //次数没到。继续重连 m_ReconnectCoroutine = m_ConnectionManager.NetworkManager.StartCoroutine(ReconnectCoroutine()); } else { //次数到了,还是连不上,跳转到OfflineState MessageCenter.SendMessage(EventDefine.ConnectStatusEvent, ConnectStatus.GenericDisconnect); m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline); } } //服务端主动断开连接。切换到DisconnectingWithReasonState。异常处理 public override void OnDisconnectReasonReceived(ConnectStatus disconnectReason) { MessageCenter.SendMessage(EventDefine.ConnectStatusEvent, disconnectReason); //MessageCenter.SendMessage(EventDefine.ClientDisConnectionEvent, disconnectReason); switch(disconnectReason) { case ConnectStatus.UserRequestedDisconnect: case ConnectStatus.HostEndedSession: case ConnectStatus.ServerFull: m_ConnectionManager.ChangeState(m_ConnectionManager.m_DisconnectingWithReason); break; } } //开启断线重连 IEnumerator ReconnectCoroutine() { //如果不是第一次重连,则等待一段时间(当问题是临时的,可以预留一些时间让其自修复)。也可以用Exponential Backoff方式来处理 if(curAttempts > 0) { yield return new WaitForSeconds(TimeBetweenAttempts); } Debug.Log("Lost connection to host, trying to reconnect..."); //先关闭 m_ConnectionManager.NetworkManager.Shutdown(); //等待直到NetworkManager完全关闭 yield return new WaitWhile(() => m_ConnectionManager.NetworkManager.ShutdownInProgress); //重连次数++ curAttempts++; Debug.Log($"Reconnecting attempt {curAttempts}/{m_ConnectionManager.ReconnectAttempts}..."); //触发消息 //MessageCenter.SendMessage(EventDefine.ConnectStatusEvent, ConnectStatus.Reconnecting); //MessageCenter.SendMessage(EventDefine.ClientReConnectionEvent, new ReconnectMessage(curAttempts, m_ConnectionManager.ReconnectAttempts)); //开始连接 Task connectingClient = ConnectClientAsync(); yield return new WaitUntil(() => connectingClient.IsCompleted); } }