| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using Cysharp.Threading.Tasks; |
| | | |
| | | public enum NetworkType |
| | | { |
| | | TCP, // 使用原有的 TCP Socket |
| | | WebSocket // 使用 WebSocket(小游戏平台) |
| | | } |
| | | |
| | | public class GameNetSystem : Singleton<GameNetSystem> |
| | | { |
| | | //限制客户端的下一个包是登录包C0101_tagCPlayerLogin,如果不是登录包不允许发送 |
| | | bool waitLogin = false; //等待发送登录包,如果有其他包直接屏蔽,避免断线重连的情况发了攻击包之类的 |
| | | //等待服务端0403的包后才能发其他的功能包,只有C0123_tagCClientPackVersion 和 C0101_tagCPlayerLogin 可以发送 |
| | | bool waitLoginMap = false; |
| | | |
| | | // 网络服务接口(统一支持 TCP 和 WebSocket) |
| | | private INetworkService networkService; |
| | | |
| | | bool waitLoginMap = false; |
| | | NetUpdateBehaviour m_NetUpdateBehaviour; |
| | | NeverConnectState neverConnectState; |
| | | AccountLoginState accountLoginState; |
| | |
| | | } |
| | | } |
| | | |
| | | private ClientSocket mainSocket; // 保留兼容,但不再直接使用 |
| | | |
| | | public bool mainSocketConnected |
| | | { |
| | | get { return networkService?.IsConnected ?? false; } |
| | | } |
| | | private ClientSocket mainSocket; |
| | | public bool mainSocketConnected { get { return mainSocket == null ? false : mainSocket.connected; } } |
| | | |
| | | public float timeSinceMainSocketLastProtocol |
| | | { |
| | | get |
| | | { |
| | | if (networkService == null) |
| | | return Time.time; |
| | | |
| | | var lastTime = networkService.LastPackageTime; |
| | | if (lastTime == DateTime.MinValue) |
| | | return Time.time; // 从未收包 |
| | | |
| | | return (float)(DateTime.Now - lastTime).TotalSeconds; |
| | | } |
| | | get { return mainSocket == null ? Time.time : (float)(DateTime.Now - mainSocket.lastPackageTime).TotalSeconds; } |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | try |
| | | { |
| | | if (networkService != null && networkService.IsConnected) |
| | | if (mainSocketConnected) |
| | | { |
| | | networkService.Disconnect(); |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | | |
| | | // 根据 Main.CurrentNetworkType 选择网络类型 |
| | | Debug.Log($"[GameNetSystem] 连接服务器 {ip}:{port},使用{(Main.CurrentNetworkType == NetworkType.WebSocket ? "WebSocket" : "TCP")}"); |
| | | |
| | | if (Main.CurrentNetworkType == NetworkType.WebSocket) |
| | | { |
| | | // 使用 WebSocket |
| | | ConnectWithWebSocket(ip, port, onConnected); |
| | | } |
| | | else |
| | | { |
| | | // 使用 TCP Socket(通过适配器) |
| | | ConnectWithTCP(ip, port, onConnected); |
| | | } |
| | | } |
| | | |
| | | private async void ConnectWithTCP(string ip, int port, Action<bool> onConnected) |
| | | { |
| | | try |
| | | { |
| | | // 创建 TCP Socket 适配器(不修改 ClientSocket) |
| | | networkService = new ClientSocketAdapter(ServerType.Main); |
| | | |
| | | // 订阅状态事件 |
| | | networkService.OnStateChanged += OnNetworkStateChanged; |
| | | |
| | | // 连接 |
| | | string url = $"{ip}:{port}"; |
| | | Debug.Log($"[GameNetSystem] TCP 开始连接: {url}"); |
| | | bool success = await networkService.ConnectAsync(url); |
| | | |
| | | Debug.Log($"[GameNetSystem] TCP 连接{(success ? "成功" : "失败")}: {url}"); |
| | | |
| | | // 兼容:保留 mainSocket 引用(但通过 networkService 访问) |
| | | mainSocket = (networkService as ClientSocketAdapter)?.GetClientSocket(); |
| | | |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(success); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.LogError($"[GameNetSystem] TCP 连接异常: {ex.Message}"); |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private async void ConnectWithWebSocket(string ip, int port, Action<bool> onConnected) |
| | | { |
| | | try |
| | | { |
| | | // 创建 WebSocket 服务(传入 ServerType,与 ClientSocket 一致) |
| | | networkService = new WebSocketNetworkService(ServerType.Main); |
| | | |
| | | // 订阅状态事件 |
| | | networkService.OnStateChanged += OnNetworkStateChanged; |
| | | |
| | | string url = $"ws://{ip}:{port}"; |
| | | Debug.Log($"[GameNetSystem] WebSocket 开始连接: {url}"); |
| | | bool success = await networkService.ConnectAsync(url); |
| | | |
| | | Debug.Log($"[GameNetSystem] WebSocket 连接{(success ? "成功" : "失败")}: {url}"); |
| | | |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(success); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.LogError($"[GameNetSystem] WebSocket 连接异常: {ex.Message}"); |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnNetworkStateChanged(NetworkState state) |
| | | { |
| | | Debug.Log($"[GameNetSystem] 网络状态变化: {state}"); |
| | | |
| | | // 断开连接时触发断线处理 |
| | | if (state == NetworkState.Disconnected || state == NetworkState.Closed) |
| | | mainSocket = new ClientSocket(ServerType.Main); |
| | | // websocket的断开链接需要处理一下 |
| | | mainSocket.OnDisconnected = () => |
| | | { |
| | | netState = NetState.DisConnected; |
| | | } |
| | | LoginManager.Instance.busy = false; |
| | | }; |
| | | mainProtocolQueue.Clear(); |
| | | |
| | | mainSocket.Connect(ip, port, (bool ok) => |
| | | { |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(ok); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | //限制客户端的下一个包是登录包C0101_tagCPlayerLogin,如果不是登录包不允许发送 |
| | |
| | | public void SendCachePackage() |
| | | { |
| | | int cnt = sendQueue.Count; |
| | | while (sendQueue.Count > 0) |
| | | if (mainSocket != null) |
| | | { |
| | | SendInfo(sendQueue.Dequeue()); |
| | | while (sendQueue.Count > 0) |
| | | { |
| | | SendInfo(sendQueue.Dequeue()); |
| | | } |
| | | } |
| | | Debug.Log($"重点提醒:0403登录后 发送缓存包数量 {cnt} 个"); |
| | | Debug.LogError($"重点提醒:0403登录后 发送缓存包数量 {cnt} 个"); |
| | | } |
| | | |
| | | public void SendInfo(GameNetPackBasic protocol) |
| | | { |
| | | Debug.LogError("protocol to send: " + protocol.ToString()); |
| | | |
| | | if (waitLogin) |
| | | { |
| | | if (protocol is not C0101_tagCPlayerLogin) |
| | |
| | | } |
| | | } |
| | | |
| | | if (networkService != null) |
| | | if (mainSocket != null) |
| | | { |
| | | networkService.SendInfo(protocol); |
| | | mainSocket.SendInfo(protocol); |
| | | DebugPkgCache.Push(protocol); |
| | | } |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | public void SendInfo(byte[] vBytes) |
| | | { |
| | | if (networkService != null) |
| | | if (mainSocket != null) |
| | | { |
| | | networkService.SendInfo(vBytes); |
| | | mainSocket.SendInfo(vBytes); |
| | | } |
| | | } |
| | | |
| | | #endif |
| | | |
| | | public void PushPackage(GameNetPackBasic protocol, ServerType type) |
| | | { |
| | |
| | | { |
| | | try |
| | | { |
| | | if (networkService != null) |
| | | if (mainSocket != null) |
| | | { |
| | | networkService.Disconnect(); |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | |
| | | { |
| | | try |
| | | { |
| | | if (networkService != null) |
| | | if (mainSocket != null) |
| | | { |
| | | networkService.Disconnect(); |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | |
| | | { |
| | | SDKUtils.Instance.RoleLoginOut(); |
| | | |
| | | if (networkService != null) |
| | | if (mainSocket != null) |
| | | { |
| | | networkService.Disconnect(); |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | |
| | | |
| | | void OnUpdate() |
| | | { |
| | | if (networkService != null) |
| | | { |
| | | if (networkService is WebSocketNetworkService wsService) { wsService.Update(); } |
| | | } |
| | | mainSocket?.DispatchMessageQueue(); |
| | | |
| | | lock (this) |
| | | { |