ConnectionManager.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. using Rokid.MRC;
  2. using System;
  3. using System.Collections.Generic;
  4. using Unity.Collections;
  5. using Unity.Netcode;
  6. using UnityEngine;
  7. //连接状态
  8. public enum ConnectStatus
  9. {
  10. Undefined,
  11. Success,
  12. ServerFull, //服务端连接数已满
  13. LoggedInAgain, //其他客户端登录,掉线
  14. UserRequestedDisconnect, //客户端主动断开连接
  15. GenericDisconnect, //断开连接
  16. Reconnecting, //断线重连
  17. IncompatibleBuildType, //客户端的Build类型不符合服务端的要求。如果客户端是Debug版本,不允许连接
  18. HostEndedSession, //Host服务端主动关闭连接
  19. StartHostFailed, //启动Host服务端失败
  20. StartClientFailed, //启动Client失败
  21. AlreadyHaveVideoClient, //只能有一个视频流
  22. }
  23. public struct ReconnectMessage
  24. {
  25. public int CurrentAttempt;
  26. public int MaxAttempt;
  27. public ReconnectMessage(int currentAttempt, int maxAttempt)
  28. {
  29. CurrentAttempt = currentAttempt;
  30. MaxAttempt = maxAttempt;
  31. }
  32. }
  33. public struct ConnectionEventMessage : INetworkSerializeByMemcpy
  34. {
  35. public ConnectStatus ConnectStatus;
  36. public string PlayerName;
  37. }
  38. public static class EventDefine
  39. {
  40. //网络连接
  41. public static readonly string ServerConnectionEvent = "ServerConnectionEvent";
  42. public static readonly string ClientReConnectionEvent = "ClientReConnectionEvent";
  43. public static readonly string ClientDisConnectionEvent = "ClientDisConnectionEvent";
  44. public static readonly string ConnectStatusEvent = "ConnectStatusEvent";
  45. }
  46. //连接状态机管理器
  47. public class ConnectionManager : Singleton<ConnectionManager>
  48. {
  49. //当前的连接状态
  50. [SerializeField]
  51. public ConnectionState m_CurrentState;
  52. public NetworkManager NetworkManager;
  53. //重连次数
  54. public int ReconnectAttempts = 2;
  55. //最大连接数
  56. public int MaxConnectedPlayers = 8;
  57. //初始化几个状态
  58. internal readonly OfflineState m_Offline = new OfflineState();
  59. //连接
  60. public ConnectionMethodIP ConnectionMethod;
  61. private ProfileManager m_ProfileManager;
  62. //客户端:OfflineState——ClientConnectingState——ClientConnectedState——ClientReconnectingState(断线重连)/OfflineState(服务端被动断连)/DisconnectingWithReasonState(服务端主动断连)
  63. internal readonly ClientConnectingState m_ClientConnecting = new ClientConnectingState();
  64. internal readonly ClientConnectedState m_ClientConnected = new ClientConnectedState();
  65. internal readonly ClientReconnectingState m_ClientReconnecting = new ClientReconnectingState();
  66. internal readonly DisconnectingWithReasonState m_DisconnectingWithReason = new DisconnectingWithReasonState();
  67. //服务端:OfflineState——StartingHostState——OfflineState(启动失败)/HostingState(启动成功)
  68. internal readonly StartingHostState m_StartingHost = new StartingHostState();
  69. internal readonly HostingState m_Hosting = new HostingState();
  70. private List<ConnectionState> connectionStateList;
  71. public override void Init()
  72. {
  73. List<ConnectionState> connectionStateList = new List<ConnectionState>()
  74. {
  75. m_Offline,
  76. m_ClientConnecting,
  77. m_ClientConnected,
  78. m_ClientReconnecting,
  79. m_DisconnectingWithReason,
  80. m_StartingHost,
  81. m_Hosting
  82. };
  83. //初始化每个状态
  84. foreach(var state in connectionStateList)
  85. {
  86. state.m_ConnectionManager = this;
  87. }
  88. m_CurrentState = m_Offline;
  89. NetworkManager.OnClientConnectedCallback += OnClientConnectedCallback;
  90. NetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback;
  91. NetworkManager.OnServerStarted += OnServerStarted;
  92. NetworkManager.ConnectionApprovalCallback += ApprovalCheck;
  93. NetworkManager.OnTransportFailure += OnTransportFailure;
  94. ConnectionMethod = new ConnectionMethodIP(this, m_ProfileManager);
  95. }
  96. public void SetNetworkManager(NetworkManager manager)
  97. {
  98. NetworkManager = manager;
  99. }
  100. public override void OnDestroy()
  101. {
  102. base.OnDestroy();
  103. NetworkManager.OnClientConnectedCallback -= OnClientConnectedCallback;
  104. NetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback;
  105. NetworkManager.OnServerStarted -= OnServerStarted;
  106. NetworkManager.ConnectionApprovalCallback -= ApprovalCheck;
  107. NetworkManager.OnTransportFailure -= OnTransportFailure;
  108. }
  109. internal void ChangeState(ConnectionState nextState)
  110. {
  111. Debug.Log($"ChangeState: Changed connection state from {m_CurrentState.GetType().Name} to {nextState.GetType().Name}.");
  112. if(m_CurrentState != null)
  113. {
  114. m_CurrentState.Exit();
  115. }
  116. m_CurrentState = nextState;
  117. m_CurrentState.Enter();
  118. }
  119. void OnClientDisconnectCallback(ulong clientId)
  120. {
  121. m_CurrentState.OnClientDisconnect(clientId);
  122. }
  123. void OnClientConnectedCallback(ulong clientId)
  124. {
  125. m_CurrentState.OnClientConnected(clientId);
  126. }
  127. void OnServerStarted()
  128. {
  129. m_CurrentState.OnServerStarted();
  130. }
  131. void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
  132. {
  133. m_CurrentState.ApprovalCheck(request, response);
  134. }
  135. void OnTransportFailure()
  136. {
  137. m_CurrentState.OnTransportFailure();
  138. }
  139. public void StartClientIp(string ipaddress, int port)
  140. {
  141. m_CurrentState.StartClientIP(ipaddress, port);
  142. }
  143. public void StartHostIp(string ipaddress, int port)
  144. {
  145. m_CurrentState.StartHostIP(ipaddress, port);
  146. }
  147. //外部调用,客户端主动发起断开
  148. public void RequestShutdown()
  149. {
  150. m_CurrentState.OnUserRequestedShutdown();
  151. }
  152. //-------------------------------自定义消息处理
  153. //自定义的消息,当调用NetworkManager.StartClient方法,就会初始化NetworkSceneManager和CustomMessagingManager,同时回调此处方法
  154. public void RegisterCustomMessages()
  155. {
  156. NetworkManager.CustomMessagingManager.RegisterNamedMessageHandler(nameof(ReceiveServerToClientSetDisconnectReason_CustomMessage), ReceiveServerToClientSetDisconnectReason_CustomMessage);
  157. }
  158. //客户端收到服务端的断开连接,并附加原因
  159. void ReceiveServerToClientSetDisconnectReason_CustomMessage(ulong clientID, FastBufferReader reader)
  160. {
  161. reader.ReadValueSafe(out ConnectStatus status);
  162. m_CurrentState.OnDisconnectReasonReceived(status);
  163. }
  164. //发送DisconnectReason信息给所有客户端
  165. public void SendServerToAllClientsSetDisconnectReason(ConnectStatus status)
  166. {
  167. var writer = new FastBufferWriter(sizeof(ConnectStatus), Allocator.Temp);
  168. writer.WriteValueSafe(status);
  169. NetworkManager.CustomMessagingManager.SendNamedMessageToAll(nameof(ReceiveServerToClientSetDisconnectReason_CustomMessage), writer);
  170. }
  171. //发送DisconnectReason信息给indicated客户端
  172. public void SendServerToClientSetDisconnectReason(ulong clientID, ConnectStatus status)
  173. {
  174. var writer = new FastBufferWriter(sizeof(ConnectStatus), Allocator.Temp);
  175. writer.WriteValueSafe(status);
  176. NetworkManager.CustomMessagingManager.SendNamedMessage(nameof(ReceiveServerToClientSetDisconnectReason_CustomMessage), clientID, writer);
  177. }
  178. }