using System; using System.Net; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Chat; /// /// 聊天服务 /// class ChatServer : MonoSingleton { public enum State { /// /// 未初始化, 需要初始化 /// UnInited = 0, /// /// 已初始化, 需要登录 /// Inited = 1, /// /// 已登录, 可以上报伤害以及自己的剩余血量 /// Logined = 2, /// /// 离开房间, 不可以继续上报伤害和剩余血量 /// Leaved = 3 } TasPBSocketManager socket; readonly Queue _netMessageDataQueue = new Queue(); /// /// 当前状态 /// public State CurrentState { get; private set; } /// /// 先初始化 /// public void Init() { var ip = "192.168.10.17"; if (GlobalConfig.netType == eNetType.Online || GlobalConfig.netType == eNetType.TestOnline) { var uri = "ylsjtt.game7000.com"; IPHostEntry entry = Dns.GetHostEntry(uri); if (entry != null && entry.AddressList != null && entry.AddressList.Length > 0) { IPAddress addr = entry.AddressList[0]; //使用时使用AddressList[0]即可 ip = addr.ToString(); } } socket = new TasPBSocketManager(); socket.Connect(ip, GlobalConfig.CharServerPort); // 挂载 服务端消息回调处理函数 MessageCenter.Instance.addObsever(eProtocalCommand.ScChatNewMsg, On_NewMessage); MessageCenter.Instance.addObsever(eProtocalCommand.ScChatLogin, On_LoginOver); this.CurrentState = State.Inited; var p = UserProxy.Instance.player; if (null != p) { this.Login(p.uid, p.baseInfo.name, p.zoneid); } else { LogHelper.LogError("此时玩家尚未完成登录, 无法取得玩家信息, 聊天登录时无个人信息可供初始化!"); } //DontDestroyOnLoad(this.gameObject); } #region 向服务端发送消息 /// /// 进入房间后发送第一条消息 /// /// /// void Login(string uid, string name, int zoneid) { UnityEngine.Debug.Assert(CurrentState == State.Inited, $"当前状态不可以执行login,({CurrentState})"); if (CurrentState == State.Inited) { var msg = new CS_ChatLogin() { Uid = uid, Name = name, Zoneid = zoneid }; socket.SendMsg(eProtocalCommand.CsChatLogin, msg); LogHelper.Log("Chat模块发送登录请求"); } } /// /// 上报伤害 /// /// public void SendMessage(ChatChannel channl, string message) { UnityEngine.Debug.Assert(CurrentState == State.Logined, $"当前状态不可以执行发送消息,({CurrentState})"); if (CurrentState == State.Logined) { var msg = new CS_ChatSendMsg() { ToChannel = channl, Msg = message }; socket.SendMsg(eProtocalCommand.CsChatSendMsg, msg); } } public void SendPrivateMessage(string toNickName, string message) { UnityEngine.Debug.Assert(CurrentState == State.Logined, $"当前状态不可以执行发送消息,({CurrentState})"); if (CurrentState == State.Logined) { var msg = new CS_ChatSendMsg() { ToChannel = ChatChannel.Single, ToNickName = toNickName, Msg = message }; socket.SendMsg(eProtocalCommand.CsChatSendMsg, msg); } } /// /// 尝试获取信消息 /// /// /// public bool TryReadMessage(out SC_ChatNewMsg msg) { if (_netMessageDataQueue.Count > 0) { msg = _netMessageDataQueue.Dequeue(); return true; } msg = null; return false; } #endregion #region 服务端消息回调 /// /// 错误信息 /// /// /// static string _loginErrInfo(SC_ChatLogin.Types.ErrorCode errCode) { switch (errCode) { case SC_ChatLogin.Types.ErrorCode.AccIdinvalid: return "uid非法"; case SC_ChatLogin.Types.ErrorCode.LoginRepeat: return "重复登录"; case SC_ChatLogin.Types.ErrorCode.InnerError: return "内部错误"; default: return "未知错误!"; } } void On_LoginOver(byte[] _data) { var msg = SC_ChatLogin.Parser.ParseFrom(_data); if (msg != null) { if (msg.Code == SC_ChatLogin.Types.ErrorCode.Ok) { CurrentState = State.Logined; LogHelper.Log("聊天服务器登录成功"); } else { LogHelper.Log("聊天模块登录失败" + _loginErrInfo(msg.Code)); } } else { LogHelper.Log("聊天模块登录返回消息解析失败!"); } } /// /// 信道名称 /// /// /// static string ChannelName(ChatChannel c) { switch (c) { case ChatChannel.System: return "系统"; case ChatChannel.World: return "世界"; case ChatChannel.Guild: return "公会"; default: return "x"; } } void On_NewMessage(byte[] _data) { var msg = SC_ChatNewMsg.Parser.ParseFrom(_data); LogHelper.Log($"[{ChannelName(msg.FromChannel)}]-[{msg.SenderName}] : " + msg.Msg); // todo : 转接客户端逻辑 _netMessageDataQueue.Enqueue(msg); } #endregion #region ' 其他辅助函数 ' void _close() { MessageCenter.Instance.removeObserver(eProtocalCommand.ScChatNewMsg, On_NewMessage); MessageCenter.Instance.removeObserver(eProtocalCommand.ScChatLogin, On_LoginOver); if (null != socket) { LogHelper.Log("聊天模块销毁socket"); socket.Close(); socket = null; } } public void Update() { if (null != socket) { socket.Update(); } } private void OnDisable() { _close(); } protected override void DoOnDestroy() { _close(); } #endregion }