星火直播PC
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

WSocketClient.cs 12KB

3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
3年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. using Common.system;
  2. using Newtonsoft.Json.Linq;
  3. using SuperSocket.ClientEngine;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using WebSocket4Net;
  9. using XHZB.Model;
  10. namespace XHZB.Desktop.WebSocket
  11. {
  12. public class WSocketClient : IDisposable
  13. {
  14. // 打开的窗口列表
  15. private static readonly Dictionary<Type, object> WinDic = new Dictionary<Type, object>();
  16. private static WSocketClient instance;
  17. public static WSocketClient getInstance()
  18. {
  19. if (instance == null)
  20. {
  21. instance = new WSocketClient();
  22. }
  23. return instance;
  24. }
  25. public static NLog.Logger _Logger = NLog.LogManager.GetCurrentClassLogger();
  26. #region 向外传递数据事件
  27. public event Action<string> MessageReceived;
  28. #endregion
  29. WebSocket4Net.WebSocket _webSocket;
  30. /// <summary>
  31. /// 检查重连线程
  32. /// </summary>
  33. Thread _thread;
  34. /// <summary>
  35. /// 心跳
  36. /// </summary>
  37. Thread thread;
  38. bool _isRunning = true;
  39. /// <summary>
  40. /// WebSocket连接地址
  41. /// </summary>
  42. public string ServerPath { get; set; }
  43. //public WSocketClient()
  44. //{
  45. // string url = "ws://schoolwstest.xhkjedu.com/ws";
  46. // ServerPath = url;
  47. // this._webSocket = new WebSocket4Net.WebSocket(url);
  48. // this._webSocket.Opened += WebSocket_Opened;
  49. // this._webSocket.Error += WebSocket_Error;
  50. // this._webSocket.Closed += WebSocket_Closed;
  51. // this._webSocket.MessageReceived += WebSocket_MessageReceived;
  52. // //注册消息接收事件,接收服务端发送的数据
  53. // MessageReceived += (data) => {
  54. // Console.WriteLine(data);
  55. // };
  56. // //开始链接
  57. // Start();
  58. // SendMessage(SocketMsgManger.offlineMsg());
  59. //}
  60. public void StartWsClient()
  61. {
  62. string url = "ws://schoolwstest.xhkjedu.com/ws";
  63. ServerPath = url;
  64. this._webSocket = new WebSocket4Net.WebSocket(url);
  65. this._webSocket.Opened += WebSocket_Opened;
  66. this._webSocket.Error += WebSocket_Error;
  67. this._webSocket.Closed += WebSocket_Closed;
  68. this._webSocket.MessageReceived += WebSocket_MessageReceived;
  69. //注册消息接收事件,接收服务端发送的数据
  70. MessageReceived += (data) =>
  71. {
  72. Console.WriteLine(data);
  73. };
  74. //开始链接
  75. Start();
  76. SendMessage(SocketMsgManger.offlineMsg());
  77. }
  78. #region "web socket "
  79. /// <summary>
  80. /// 连接方法
  81. /// <returns></returns>
  82. public bool Start()
  83. {
  84. bool result = true;
  85. try
  86. {
  87. this._webSocket.Open();
  88. this._isRunning = true;
  89. this._thread = new Thread(new ThreadStart(CheckConnection));
  90. this._thread.Start();
  91. thread = new Thread(new ThreadStart(Heartbeat));
  92. thread.Start();
  93. }
  94. catch (Exception ex)
  95. {
  96. _Logger.Error(ex.ToString());
  97. result = false;
  98. }
  99. return result;
  100. }
  101. /// <summary>
  102. /// 消息收到事件
  103. /// </summary>
  104. /// <param name="sender"></param>
  105. /// <param name="e"></param>
  106. void WebSocket_MessageReceived(object sender, MessageReceivedEventArgs e)
  107. {
  108. _Logger.Info(" Received:" + e.Message);
  109. MessageReceived?.Invoke(e.Message);
  110. Console.WriteLine("WS:消息收到:" + e.Message);
  111. //string str = e.Message;
  112. // JObject.Parse(str);
  113. //string str = jo["c"].ToString();
  114. SocketModel msgBean = JsonHelper.JsonToObj<SocketModel>(e.Message);
  115. //if(isMsg)
  116. // {
  117. // GetOnlineStudentsModel msgBean = JsonHelper.JsonToObj<GetOnlineStudentsModel>(e.Message);
  118. // if (msgBean.c == 1040)
  119. // {
  120. // }
  121. // }
  122. if (msgBean != null && msgBean.b != null)
  123. {
  124. if (msgBean.c == 1040)
  125. {
  126. GetOnlineStudentsModel msgOnline = JsonHelper.JsonToObj<GetOnlineStudentsModel>(e.Message);
  127. foreach (StudentModel getOnline in msgOnline.b.stulst)
  128. {
  129. OnlineUserModel item = new OnlineUserModel();
  130. if (getUserByIds(getOnline.userid) == null)
  131. {
  132. item.usertype = 2001;
  133. item.userid = getOnline.userid;
  134. item.username = getOnline.username;
  135. item.userpic = getOnline.headportrait;
  136. APP.OnlineUserList.Add(item);
  137. }
  138. }
  139. return;
  140. }
  141. //GetOnlineStudentsModel get = new GetOnlineStudentsModel();
  142. //get.b = new StulstModel();
  143. //Console.WriteLine("WS:消息收到1111:" + get);
  144. }
  145. if (msgBean.c != 0 && msgBean.u == 2)
  146. {
  147. if (msgBean.c == 2001)//上线
  148. {
  149. if(getUserByIds(msgBean.b.stid) == null)
  150. {
  151. OnlineUserModel item = new OnlineUserModel
  152. {
  153. usertype = msgBean.c,
  154. userid = msgBean.b.stid,
  155. username = msgBean.b.stname,
  156. userpic = msgBean.b.stpic
  157. };
  158. APP.OnlineUserList.Add(item);
  159. sendUserChangeToWin();
  160. }
  161. }
  162. else if (msgBean.c == 2002)//下线
  163. {
  164. try
  165. {
  166. for (int i = 0; i < APP.OnlineUserList.Count; i++)
  167. {
  168. if (msgBean.b.stid == APP.OnlineUserList[i].userid)
  169. {
  170. APP.OnlineUserList.RemoveAt(i);
  171. break;
  172. }
  173. }
  174. }
  175. catch (Exception ex)
  176. {
  177. LogHelper.WriteErrLog("(移除)" + ex.Message, ex);
  178. }
  179. sendUserChangeToWin();
  180. }
  181. sendMsgToWin(msgBean);
  182. }
  183. }
  184. /// <summary>
  185. /// 是否存在用户
  186. /// </summary>
  187. /// <param name="userid"></param>
  188. /// <returns></returns>
  189. public OnlineUserModel getUserByIds(int userid)
  190. {
  191. if (APP.OnlineUserList.Count > 0)
  192. {
  193. OnlineUserModel[] userList = APP.OnlineUserList.ToArray();
  194. foreach (OnlineUserModel user in userList)
  195. {
  196. if (user != null)
  197. {
  198. if (user.userid == userid)
  199. {
  200. return user;
  201. }
  202. }
  203. }
  204. }
  205. return null;
  206. }
  207. private static void sendMsgToWin(SocketModel msg)
  208. {
  209. foreach (KeyValuePair<Type, object> kvp in WinDic)
  210. {
  211. if (kvp.Value is SocketCallback callback)
  212. {
  213. callback.receiveWsMsg(msg);
  214. }
  215. }
  216. }
  217. /// <summary>
  218. /// 添加要推送消息的窗口
  219. /// </summary>
  220. /// <param name="win"></param>
  221. public void addWin(object win)
  222. {
  223. if (WinDic.ContainsKey(win.GetType()))
  224. {
  225. WinDic[win.GetType()] = win;
  226. }
  227. else
  228. {
  229. WinDic.Add(win.GetType(), win);
  230. }
  231. }
  232. /// <summary>
  233. /// 发送给需要接收的窗口
  234. /// </summary>
  235. private static void sendUserChangeToWin()
  236. {
  237. foreach (KeyValuePair<Type, object> kvp in WinDic)
  238. {
  239. if (kvp.Value is SocketCallback callback)
  240. {
  241. callback.userListChange();
  242. }
  243. }
  244. }
  245. /// <summary>
  246. /// 移除窗口
  247. /// </summary>
  248. /// <param name="win"></param>
  249. public void removedWin(object win)
  250. {
  251. if (WinDic.ContainsKey(win.GetType()))
  252. {
  253. WinDic.Remove(win.GetType());
  254. }
  255. }
  256. /// <summary>
  257. /// Socket关闭事件
  258. /// </summary>
  259. /// <param name="sender"></param>
  260. /// <param name="e"></param>
  261. void WebSocket_Closed(object sender, EventArgs e)
  262. {
  263. _Logger.Info("websocket_Closed");
  264. }
  265. /// <summary>
  266. /// Socket报错事件
  267. /// </summary>
  268. /// <param name="sender"></param>
  269. /// <param name="e"></param>
  270. void WebSocket_Error(object sender, ErrorEventArgs e)
  271. {
  272. _Logger.Info("websocket_Error:" + e.Exception.ToString());
  273. }
  274. /// <summary>
  275. /// Socket打开事件
  276. /// </summary>
  277. /// <param name="sender"></param>
  278. /// <param name="e"></param>
  279. void WebSocket_Opened(object sender, EventArgs e)
  280. {
  281. SendMessage(SocketMsgManger.AddMsg());
  282. _Logger.Info(" websocket_Opened");
  283. SendMessage(SocketMsgManger.offlineMsg());
  284. }
  285. /// <summary>
  286. /// 检查重连线程
  287. /// </summary>
  288. private void CheckConnection()
  289. {
  290. do
  291. {
  292. try
  293. {
  294. if (this._webSocket.State != WebSocket4Net.WebSocketState.Open && this._webSocket.State != WebSocket4Net.WebSocketState.Connecting)
  295. {
  296. _Logger.Info(" Reconnect websocket WebSocketState:" + this._webSocket.State);
  297. this._webSocket.Close();
  298. this._webSocket.Open();
  299. Console.WriteLine("正在重连");
  300. }
  301. }
  302. catch (Exception ex)
  303. {
  304. _Logger.Error(ex.ToString());
  305. }
  306. System.Threading.Thread.Sleep(5000);
  307. } while (this._isRunning);
  308. }
  309. /// <summary>
  310. /// 心跳
  311. /// </summary>
  312. private void Heartbeat()
  313. {
  314. do
  315. {
  316. try
  317. {
  318. if(_webSocket != null && _webSocket.State == WebSocket4Net.WebSocketState.Open)
  319. {
  320. byte[] bt = new byte[] { 01 };
  321. _webSocket.Send(bt, 0, 1);
  322. Console.WriteLine("心跳:" + DateTime.Now.ToString());
  323. }
  324. }
  325. catch (Exception ex)
  326. {
  327. _Logger.Error(ex.ToString());
  328. }
  329. Thread.Sleep(10000);
  330. } while (true);
  331. }
  332. #endregion
  333. /// <summary>
  334. /// 发送消息
  335. /// </summary>
  336. /// <param name="Message"></param>
  337. public void SendMessage(string Message)
  338. {
  339. Task.Factory.StartNew(() =>
  340. {
  341. if (_webSocket != null && _webSocket.State == WebSocket4Net.WebSocketState.Open)
  342. {
  343. this._webSocket.Send(Message);
  344. Console.WriteLine("WS:发送消息:" + Message);
  345. }
  346. });
  347. }
  348. public void Dispose()
  349. {
  350. this._isRunning = false;
  351. try
  352. {
  353. _thread.Abort();
  354. }
  355. catch
  356. {
  357. }
  358. this._webSocket.Close();
  359. this._webSocket.Dispose();
  360. this._webSocket = null;
  361. }
  362. }
  363. }