using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TEngine; using UnityEngine; using UnityWebSocket; using System.Linq; using System.Text; using Cysharp.Threading.Tasks; using System.Net.Sockets; using System.Xml.Linq; namespace GameLogic { public class ProtCust : GameBase.Singleton { private WebSocket m_WebSocket; // 异步线程回归到主线程处理 private Dictionary> m_ListProCustMessageDatas = new Dictionary>(); Dictionary ack = new Dictionary();//json1.data.msgId Dictionary dct = new Dictionary(); Dictionary handled = new Dictionary(1000);//已处理的消息 public async void OpenWebSocket() { if (m_WebSocket != null) { // 断开连接.. m_WebSocket.CloseAsync(); m_WebSocket = null; await UniTask.Delay(1000); } // 初始化消息队列 m_ListProCustMessageDatas.Add(EventConts.GiftInfo, new List()); m_ListProCustMessageDatas.Add(EventConts.LickInfo, new List()); m_ListProCustMessageDatas.Add(EventConts.MessageInfo, new List()); switch (EventConts.PlatformType) { case PlatformType.None: NoneSocketInit(); break; case PlatformType.DyTest: DyTestSocketInit(); break; case PlatformType.Dy: DySocketInit(); break; default: Log.Error("没有支持的平台:{0}", EventConts.PlatformType); break; } } /// /// 切换网络连接平台 /// /// public async void SwitchPlatform(PlatformType platformType) { if (m_WebSocket != null) { // 断开连接.. m_WebSocket.CloseAsync(); m_WebSocket = null; await UniTask.Delay(1000); } switch (EventConts.PlatformType) { case PlatformType.None: NoneSocketInit(); break; case PlatformType.DyTest: DyTestSocketInit(); break; case PlatformType.Dy: DySocketInit(); break; default: Log.Error("没有支持的平台:{0}", EventConts.PlatformType); break; } } float timerDt = 2; public void OnUpdate() { if (m_WebSocket != null && m_WebSocket.ReadyState == WebSocketState.Open) { DOSendAck(); } foreach (var item in m_ListProCustMessageDatas) { if (item.Value.Count <= 0) { continue; } foreach (var data in item.Value) { GameEvent.Send(item.Key, data); } item.Value.Clear(); } timerDt -= Time.deltaTime; if (timerDt <= 0) { // 执行一次Ack timerDt = 2; OnHbTimer(); } } /// /// 心跳包 /// private void OnHbTimer() { // 心跳包 Dictionary dis = new Dictionary(); dis.Add("type", "hb"); m_WebSocket.SendAsync(dis.ToJson()); } /// /// 测试服流程初始化 /// private void NoneSocketInit() { int id = UnityEngine.Random.Range(0, 1000); string edit = "Jscc"; var room_id = "test" + id + edit; m_WebSocket = new WebSocket(string.Format(EventConts.ServerUrlTest, WebUtility.UrlEncode(room_id), WebUtility.UrlEncode("test" + id + edit), WebUtility.UrlEncode(EventConts.TestPlayerUrl), WebUtility.UrlEncode("测试主播" + id + edit), WebUtility.UrlEncode(EventConts.app_id_test))); // 主播信息 EventConts.RoomData = new RoomInfoData { room_id = room_id, anchor_open_id = "test" + id + edit, avatar_url = EventConts.TestPlayerUrl, nick_name = "测试主播" + id + edit, }; m_WebSocket.OnMessage += SocketOnMessage; m_WebSocket.OnError += SocketOnError; m_WebSocket.OnOpen += SocketOnOpen; m_WebSocket.ConnectAsync(); Log.Info("NoneSocket Init ...."); } private void DySocketInit() { // 获取token string[] arguments = Environment.GetCommandLineArgs(); if (arguments == null || arguments.Length == 0) { Debug.LogError("启动参数:无"); } if (arguments[1].Length < 8) { Log.Error("Token参数异常"); } string token = string.Empty; for (int i = 0; i < arguments.Length; i++) { if (arguments[i].Contains("-token")) { token = arguments[i].Substring(7); } } // 没有token 提示,关闭游戏。。 if (string.IsNullOrEmpty(token)) { // Log.Error("token获取失败"); UITip.ShowMessageBox("获取token失败,确保打开直播伴侣", MessageShowType.TwoButton, () => { DySocketInit(); }, () => { Application.Quit(); }); return; } // 设置token EventConts.Token = token; GetRoomIdData data = new GetRoomIdData { token = EventConts.Token, }; var roomJsonData = HttpSendHelper.HttpPostRequest(EventConts.GetRoomInfo, data.ToJson()); try { GetRoomDataRoot getRoomDataRoot = JsonHelper.Deserialize(roomJsonData); if (getRoomDataRoot.code == 500) { UITip.ShowMessageBox(getRoomDataRoot.msg, MessageShowType.TwoButton, () => { DySocketInit(); }, () => { Application.Quit(); }); } else { m_WebSocket = new WebSocket(string.Format(EventConts.ServerUrl, WebUtility.UrlEncode(getRoomDataRoot.data.room_id), WebUtility.UrlEncode(getRoomDataRoot.data.anchor_open_id), WebUtility.UrlEncode(getRoomDataRoot.data.avatar_url), WebUtility.UrlEncode(getRoomDataRoot.data.nick_name), WebUtility.UrlEncode(EventConts.app_id))); // 设置房间数据 EventConts.RoomData = getRoomDataRoot.data; m_WebSocket.OnMessage += SocketOnMessage; m_WebSocket.OnError += SocketOnError; m_WebSocket.OnOpen += SocketOnOpen; m_WebSocket.ConnectAsync(); Log.Info("DySocket Init ...."); } } catch (Exception e) { Debug.LogError($"GetRoomInfo 解析错误,返回值:{roomJsonData}"); UITip.ShowMessageBox("解析房间信息失败", MessageShowType.TwoButton, () => { DySocketInit(); }, () => { Application.Quit(); }); } } private void DyTestSocketInit() { int id = UnityEngine.Random.Range(0, 1000); string edit = "Jscc"; var room_id = "1222222222222222222"; m_WebSocket = new WebSocket(string.Format(EventConts.ServerUrl, WebUtility.UrlEncode(room_id), WebUtility.UrlEncode("test" + id + edit), WebUtility.UrlEncode(EventConts.TestPlayerUrl), WebUtility.UrlEncode("测试主播" + id + edit), WebUtility.UrlEncode(EventConts.app_id))); // 主播信息 EventConts.RoomData = new RoomInfoData { room_id = room_id, anchor_open_id = "test" + id + edit, avatar_url = EventConts.TestPlayerUrl, nick_name = "测试主播" + id + edit, }; m_WebSocket.OnMessage += SocketOnMessage; m_WebSocket.OnError += SocketOnError; m_WebSocket.OnOpen += SocketOnOpen; m_WebSocket.ConnectAsync(); Log.Info("DyTestSocket Init ...."); } private long timerId; private void SocketOnOpen(object o, OpenEventArgs e) { Log.Debug("连接服务器,服务器地址:{0}", (o as WebSocket).Address); if (timerId != 0) { GameModule.Timer.RemoveTimer((int)timerId); } // 增加心跳包 timerId = GameModule.Timer.AddTimer((e) => { if (m_WebSocket != null) { Dictionary dis = new Dictionary(); dis.Add("type", "hb"); dis.Add("data", "ping"); m_WebSocket.SendAsync(dis.ToJson()); } }, 5, true); } private void SocketOnMessage(object o, MessageEventArgs e) { try { // 异常数据处理 if (e.Data == null || e.Data == string.Empty) { return; } // 先根据解析出来的类型处理 var mj = JObject.Parse(e.Data); string Info = mj["type"].ToString(); // 处理消息协议 if (Info == "roundEnd") { } else if (Info != "hb") { ParentProtCustMessageData json1 = JsonConvert.DeserializeObject(e.Data); ProtCustMessageData protCustMessageData = new ProtCustMessageData(); if (json1.data == null) { return; } if (handled.ContainsKey(json1.data.msgId) == false) { handled[json1.data.msgId] = 1; switch (json1.type) { case "MemberMessage": break; case "gift": protCustMessageData.imgURL = json1.data.avatar; protCustMessageData.nickName = json1.data.name; protCustMessageData.content = json1.data.giftId; protCustMessageData.Count = json1.data.repeatCount.ToString(); protCustMessageData.openId = string.IsNullOrEmpty(json1.data.uid) ? json1.data.openId : json1.data.uid; protCustMessageData.giftValue = json1.data.giftValue; protCustMessageData.rankRo = json1.data.rankRo; protCustMessageData.customCamp = json1.data.customCamp; protCustMessageData.roomId = json1.data.roomId; // GameEvent.Send(EventConts.GiftInfo, protCustMessageData); m_ListProCustMessageDatas[EventConts.GiftInfo].Add(protCustMessageData); break; case "like": protCustMessageData.imgURL = json1.data.avatar; protCustMessageData.nickName = json1.data.name; protCustMessageData.content = "点赞"; protCustMessageData.Count = json1.data.likeCount; protCustMessageData.openId = string.IsNullOrEmpty(json1.data.uid) ? json1.data.openId : json1.data.uid; protCustMessageData.rankRo = json1.data.rankRo; protCustMessageData.customCamp = json1.data.customCamp; protCustMessageData.roomId = json1.data.roomId; // GameEvent.Send(EventConts.LickInfo, protCustMessageData); m_ListProCustMessageDatas[EventConts.LickInfo].Add(protCustMessageData); break; case "chat": protCustMessageData.imgURL = json1.data.avatar; protCustMessageData.nickName = json1.data.name; protCustMessageData.content = json1.data.comment; protCustMessageData.openId = string.IsNullOrEmpty(json1.data.uid) ? json1.data.openId : json1.data.uid; protCustMessageData.rankRo = json1.data.rankRo; protCustMessageData.customCamp = json1.data.customCamp; protCustMessageData.roomId = json1.data.roomId; // GameEvent.Send(EventConts.MessageInfo, protCustMessageData); m_ListProCustMessageDatas[EventConts.MessageInfo].Add(protCustMessageData); break; } } // 礼物消息重发 if (json1.type == "chat" || json1.type == "gift") { #region 快手相关 Dictionary dis = new Dictionary(); dis.Add("type", "dmAck"); Dictionary data = new Dictionary(); data.Add("msgId", json1.data.msgId); data.Add("ackType", "show"); dis.Add("data", data.ToJson()); m_WebSocket.SendAsync(dis.ToJson()); #endregion } } } catch (Exception es) { Log.Error(es.Message); throw; } } private void SocketOnError(object o, ErrorEventArgs e) { Log.Error("Socket Error:" + e.Message.ToString()); UITip.ShowMessageBox("网络波动请尝试重连", MessageShowType.TwoButton, () => { // socketIo.CloseAsync(); // socketIo = null; // InitSelfServer(); }, () => { // Application.Quit(); }); } #region 小摇杆快捷 public void SendRoundVo_Start() { RoundVo roundVo = new RoundVo(); roundVo.type = "PVP"; Dictionary dct = new Dictionary(); //roundStart roundEnd dct["type"] = "roundStart"; dct["data"] = roundVo.ToJson(); m_WebSocket.SendAsync(dct.ToJson()); } public void SendRoundVo_End() { RoundVo roundVo = new RoundVo(); roundVo.type = "PVP"; roundVo.winSide = "blue"; Dictionary dct = new Dictionary(); dct["type"] = "roundEnd"; dct["data"] = roundVo.ToJson(); m_WebSocket.SendAsync(dct.ToJson()); } #endregion #region GM public void SendMessage_GM(string type, ProtCustMessageData protCustMessageData) { GMMessage gmMessage = new GMMessage { type = type, nickName = protCustMessageData.nickName, openId = protCustMessageData.openId, imageUrl = protCustMessageData.imgURL, content = protCustMessageData.content, count = protCustMessageData.Count, giftValue = protCustMessageData.giftValue, customCamp = (int)protCustMessageData.customCamp, }; Dictionary dic = new Dictionary(); if (dic.Count == 0) { dic.Add("type", "gm"); } dic["data"] = gmMessage.ToJson(); var json = dic.ToJson(); SendGMMessage(json); } private void SendGMMessage(string gmMessage) { if (m_WebSocket != null) { m_WebSocket.SendAsync(gmMessage); } } #endregion public void DOSendAck() { if (ack.Count > 0) { foreach (var item in ack) { var k = item.Key; SendAckMessage(k); } ack.Clear(); } } AckData ack_data = new AckData(); public void SendAckMessage(string msg_id) { if (dct.Count == 0) { dct.Add("type", "dmAck"); } ack_data.msgId = msg_id; ack_data.ackType = "receive"; dct["data"] = ack_data.ToJson(); var content = dct.ToJson(); //Debug.LogError("发送ack:"+ content); m_WebSocket.SendAsync(content); } } }