ChatServer.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. using System;
  2. using System.Net;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Chat;
  8. /// <summary>
  9. /// 聊天服务
  10. /// </summary>
  11. class ChatServer : MonoSingleton<ChatServer>
  12. {
  13. public enum State
  14. {
  15. /// <summary>
  16. /// 未初始化, 需要初始化
  17. /// </summary>
  18. UnInited = 0,
  19. /// <summary>
  20. /// 已初始化, 需要登录
  21. /// </summary>
  22. Inited = 1,
  23. /// <summary>
  24. /// 已登录, 可以上报伤害以及自己的剩余血量
  25. /// </summary>
  26. Logined = 2,
  27. /// <summary>
  28. /// 离开房间, 不可以继续上报伤害和剩余血量
  29. /// </summary>
  30. Leaved = 3
  31. }
  32. TasPBSocketManager socket;
  33. readonly Queue<SC_ChatNewMsg> _netMessageDataQueue = new Queue<SC_ChatNewMsg>();
  34. /// <summary>
  35. /// 当前状态
  36. /// </summary>
  37. public State CurrentState { get; private set; }
  38. /// <summary>
  39. /// 先初始化
  40. /// </summary>
  41. public void Init()
  42. {
  43. var ip = "192.168.10.17";
  44. if (GlobalConfig.netType == eNetType.Online || GlobalConfig.netType == eNetType.TestOnline)
  45. {
  46. var uri = "ylsjtt.game7000.com";
  47. IPHostEntry entry = Dns.GetHostEntry(uri);
  48. if (entry != null && entry.AddressList != null && entry.AddressList.Length > 0)
  49. {
  50. IPAddress addr = entry.AddressList[0]; //使用时使用AddressList[0]即可
  51. ip = addr.ToString();
  52. }
  53. }
  54. socket = new TasPBSocketManager();
  55. socket.Connect(ip, GlobalConfig.CharServerPort);
  56. // 挂载 服务端消息回调处理函数
  57. MessageCenter.Instance.addObsever(eProtocalCommand.ScChatNewMsg, On_NewMessage);
  58. MessageCenter.Instance.addObsever(eProtocalCommand.ScChatLogin, On_LoginOver);
  59. this.CurrentState = State.Inited;
  60. var p = UserProxy.Instance.player;
  61. if (null != p)
  62. {
  63. this.Login(p.uid, p.baseInfo.name, p.zoneid);
  64. }
  65. else
  66. {
  67. LogHelper.LogError("此时玩家尚未完成登录, 无法取得玩家信息, 聊天登录时无个人信息可供初始化!");
  68. }
  69. //DontDestroyOnLoad(this.gameObject);
  70. }
  71. #region 向服务端发送消息
  72. /// <summary>
  73. /// 进入房间后发送第一条消息
  74. /// </summary>
  75. /// <param name="uid"></param>
  76. /// <param name="zoneid"></param>
  77. void Login(string uid, string name, int zoneid)
  78. {
  79. UnityEngine.Debug.Assert(CurrentState == State.Inited, $"当前状态不可以执行login,({CurrentState})");
  80. if (CurrentState == State.Inited)
  81. {
  82. var msg = new CS_ChatLogin() { Uid = uid, Name = name, Zoneid = zoneid };
  83. socket.SendMsg(eProtocalCommand.CsChatLogin, msg);
  84. LogHelper.Log("Chat模块发送登录请求");
  85. }
  86. }
  87. /// <summary>
  88. /// 上报伤害
  89. /// </summary>
  90. /// <param name="damage"></param>
  91. public void SendMessage(ChatChannel channl, string message)
  92. {
  93. UnityEngine.Debug.Assert(CurrentState == State.Logined, $"当前状态不可以执行发送消息,({CurrentState})");
  94. if (CurrentState == State.Logined)
  95. {
  96. var msg = new CS_ChatSendMsg() { ToChannel = channl, Msg = message };
  97. socket.SendMsg(eProtocalCommand.CsChatSendMsg, msg);
  98. }
  99. }
  100. public void SendPrivateMessage(string toNickName, string message)
  101. {
  102. UnityEngine.Debug.Assert(CurrentState == State.Logined, $"当前状态不可以执行发送消息,({CurrentState})");
  103. if (CurrentState == State.Logined)
  104. {
  105. var msg = new CS_ChatSendMsg() { ToChannel = ChatChannel.Single, ToNickName = toNickName, Msg = message };
  106. socket.SendMsg(eProtocalCommand.CsChatSendMsg, msg);
  107. }
  108. }
  109. /// <summary>
  110. /// 尝试获取信消息
  111. /// </summary>
  112. /// <param name="msg"></param>
  113. /// <returns></returns>
  114. public bool TryReadMessage(out SC_ChatNewMsg msg)
  115. {
  116. if (_netMessageDataQueue.Count > 0)
  117. {
  118. msg = _netMessageDataQueue.Dequeue();
  119. return true;
  120. }
  121. msg = null;
  122. return false;
  123. }
  124. #endregion
  125. #region 服务端消息回调
  126. /// <summary>
  127. /// 错误信息
  128. /// </summary>
  129. /// <param name="errCode"></param>
  130. /// <returns></returns>
  131. static string _loginErrInfo(SC_ChatLogin.Types.ErrorCode errCode)
  132. {
  133. switch (errCode)
  134. {
  135. case SC_ChatLogin.Types.ErrorCode.AccIdinvalid:
  136. return "uid非法";
  137. case SC_ChatLogin.Types.ErrorCode.LoginRepeat:
  138. return "重复登录";
  139. case SC_ChatLogin.Types.ErrorCode.InnerError:
  140. return "内部错误";
  141. default:
  142. return "未知错误!";
  143. }
  144. }
  145. void On_LoginOver(byte[] _data)
  146. {
  147. var msg = SC_ChatLogin.Parser.ParseFrom(_data);
  148. if (msg != null)
  149. {
  150. if (msg.Code == SC_ChatLogin.Types.ErrorCode.Ok)
  151. {
  152. CurrentState = State.Logined;
  153. LogHelper.Log("聊天服务器登录成功");
  154. }
  155. else
  156. {
  157. LogHelper.Log("聊天模块登录失败" + _loginErrInfo(msg.Code));
  158. }
  159. }
  160. else
  161. {
  162. LogHelper.Log("聊天模块登录返回消息解析失败!");
  163. }
  164. }
  165. /// <summary>
  166. /// 信道名称
  167. /// </summary>
  168. /// <param name="c"></param>
  169. /// <returns></returns>
  170. static string ChannelName(ChatChannel c)
  171. {
  172. switch (c)
  173. {
  174. case ChatChannel.System:
  175. return "系统";
  176. case ChatChannel.World:
  177. return "世界";
  178. case ChatChannel.Guild:
  179. return "公会";
  180. default:
  181. return "x";
  182. }
  183. }
  184. void On_NewMessage(byte[] _data)
  185. {
  186. var msg = SC_ChatNewMsg.Parser.ParseFrom(_data);
  187. LogHelper.Log($"[{ChannelName(msg.FromChannel)}]-[{msg.SenderName}] : " + msg.Msg);
  188. // todo : 转接客户端逻辑
  189. _netMessageDataQueue.Enqueue(msg);
  190. }
  191. #endregion
  192. #region ' 其他辅助函数 '
  193. void _close()
  194. {
  195. MessageCenter.Instance.removeObserver(eProtocalCommand.ScChatNewMsg, On_NewMessage);
  196. MessageCenter.Instance.removeObserver(eProtocalCommand.ScChatLogin, On_LoginOver);
  197. if (null != socket)
  198. {
  199. LogHelper.Log("聊天模块销毁socket");
  200. socket.Close();
  201. socket = null;
  202. }
  203. }
  204. public void Update()
  205. {
  206. if (null != socket)
  207. {
  208. socket.Update();
  209. }
  210. }
  211. private void OnDisable()
  212. {
  213. _close();
  214. }
  215. protected override void DoOnDestroy()
  216. {
  217. _close();
  218. }
  219. #endregion
  220. }