using Assets.MyGame.Scripts.Net.WebResponses; using Best.WebSockets; using Newtonsoft.Json; using System; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.SceneManagement; namespace Assets.MyGame.Scripts.Net { public enum SocketType { login, room, game, chess, customer, } public partial class WebSocketManager : MonoSingleton { private readonly Dictionary sockets = new(); private readonly Dictionary socketPaths = new(); //private const string baseUrl = "ws://game5241.wzaxr.top"; private const string baseUrl = "ws://8.137.163.153"; public bool isGame=false; protected override void Awake() { base.Awake(); socketPaths[SocketType.game] = "/gamehub"; socketPaths[SocketType.room] = "/fishingroomhub"; socketPaths[SocketType.login] = "/loginhub"; socketPaths[SocketType.chess] = "/chessgamehub"; socketPaths[SocketType.customer] = "/customerHub"; } /// /// 创建或返回已存在的 WebSocket /// public WebSocket Connect(SocketType type,Action action=null) { // 已存在则直接返回 if (sockets.TryGetValue(type, out var exist)) { if (exist.IsOpen) { Debug.Log($"[WebSocket] {type} 已连接,直接返回"); switch (type) { case SocketType.login: break; case SocketType.room: //WebSocketSendList.JoinRoom("11109", GameManager.Instance.user.id, 1); break; case SocketType.game: break; case SocketType.chess: WebSocketSendList.GetRoomListChineseChess(1); break; case SocketType.customer: break; default: break; } return exist; } } string url = baseUrl + socketPaths[type]; var ws = new WebSocket(new Uri(url)); sockets[type] = ws; // 事件绑定 ws.OnOpen += (web) => { Debug.Log($"[WebSocket] {type} 已连接: {url}"); web.Send("{\"protocol\":\"json\",\"version\":1}\u001e "); switch (type) { case SocketType.login: WebSocketSendList.Bind(GameManager.Instance.user.id); break; case SocketType.room: break; case SocketType.game: break; case SocketType.chess: break; case SocketType.customer: break; default: break; } if (action != null) action?.Invoke(); }; ws.OnClosed += (web, code, reason) => { Debug.Log($"[WebSocket] {type} 连接关闭 Code:{code} Reason:{reason}"); // 自动重连 switch (type) { case SocketType.login: break; case SocketType.room: break; case SocketType.game: if (isGame) { int sitpos = 0; foreach (var item in GameManager.Instance.gameData.currRoomData.players) { if (item.userId==GameManager.Instance.user.id) { sitpos = item.position; break; } } StartCoroutine(Reconnect(type, () => { WebSocketSendList.JoinRoom(GameManager.Instance.gameData.currRoomData.roomId, GameManager.Instance.user.id, sitpos); })); } break; case SocketType.chess: break; case SocketType.customer: break; default: break; } }; ws.OnClosed += (web, code, message) => { Debug.LogError($"[WebSocket] {type} 错误{code}: {message}"); }; ws.OnMessage += (web, msg) => { OnMessage(web, msg, type); }; // 保存 sockets[type] = ws; // 发起连接 ws.Open(); return ws; } /// /// 发送消息 /// public void Send(SocketType type, string msg) { if (sockets.TryGetValue(type, out var ws) && ws.IsOpen) { ws.Send(msg + "\u001e"); Debug.LogWarning($"[WebSocket] {type}Send :" + msg); } else { Debug.LogWarning($"[WebSocket] {type} 未连接,无法发送消息"); UIManager.Instance.ShowBoardError($"[WebSocket] {type} 未连接,无法发送消息"); } } /// /// 关闭某个 socket /// public void Close(SocketType type) { if (sockets.TryGetValue(type, out var ws)) { ws.Close(WebSocketStatusCodes.NormalClosure, "正常关闭"); // 或者 CloseStatusCode.Normal //ws.Close(); sockets.Remove(type); } } /// /// 自动重连 /// private System.Collections.IEnumerator Reconnect(SocketType type,Action action=null) { Debug.Log($"[WebSocket] {type} 3 秒后尝试重连..."); yield return new WaitForSeconds(3f); Connect(type,action); } /// /// 关闭所有 socket /// private void OnDestroy() { foreach (var ws in sockets.Values) { ws.Close(); } sockets.Clear(); } } }