using System; using System.Linq; using System.Text; using System.Threading; using System.Xml; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using WebSocket = WebSocketSharp.WebSocket; using CsharpHttpHelper; namespace Api.Framework { /// /// 通知客户端 /// public class NoticeSocketClient { /// /// 发送Ack模式通知数据 /// public class AckNoticeData : EventArgs { /// /// ID /// public string Id { get; set; } /// /// 命令ID /// public string CommonId { get; set; } /// /// 信号道 /// public string Channel { get; set; } /// /// 数据 /// public string Data { get; set; } /// /// 生成时间 /// public DateTime CreateDateTime { get; set; } /// /// 标记被删除 /// public bool IsRemove { get; set; } /// /// 重试 /// public bool IsRetry { get; set; } } /// /// 构造函数 /// /// /// public NoticeSocketClient(string host, params string[] channel) { this._host = host; this._channels = channel.ToArray(); } private readonly string[] _channels; private readonly string _host; /// /// 连接对象 /// private WebSocket _websocket; /// /// 连接状态 /// public bool IsConnected => (_websocket != null && _websocket.IsAlive); /// /// 连接 /// public void Connect() { if (IsConnected) { _websocket.OnOpen -= _websocket_OnOpen; _websocket.OnMessage -= _websocket_OnMessage; _websocket?.Close(); } _websocket = new WebSocket($"ws://{this._host}/api/push?id={DateTime.Now.Ticks}"); _websocket.OnOpen += _websocket_OnOpen; _websocket.OnMessage += _websocket_OnMessage; _websocket.Connect(); if (_thread == null) { _thread = new Thread(Ping) { IsBackground = true }; _thread.Start(); } } /// /// 收到消息事件 /// public event EventHandler OnMessageEvent; /// /// 连接成功事件 /// public event EventHandler OnConnectedEvent; private void _websocket_OnMessage(object sender, WebSocketSharp.MessageEventArgs e) { try { var index = e.Data.IndexOf("\u0000", StringComparison.Ordinal); if (index <= -1) { return; } var commonId = e.Data.Substring(0, index); if (commonId != "notice") return; var body = e.Data.Substring(index + 1); var data = JsonConvert.DeserializeObject(body); if (data == null || string.IsNullOrEmpty(data.Id)) return; this._websocket.Send("notice_ack\u0000" + data.Id); OnMessageEvent?.Invoke(this, data); } catch (Exception ex) { Console.WriteLine($"即时通讯API接收异常:{ex.Message}"); } } private Thread _thread; private void _websocket_OnOpen(object sender, System.EventArgs e) { try { foreach (var v in this._channels) { this._websocket.Send($"subchannel\u0000{v}");//订阅通道 } this.OnConnectedEvent?.Invoke(this, EventArgs.Empty); } catch (Exception ex) { Console.WriteLine($"即时通讯API连接异常:{ex.Message}"); } } private void Ping() { while (true) { Thread.Sleep(1000 * 10); try { //测试ping是否正常 if (this._websocket.Ping()) continue; //断开自动重连 this.Connect(); } catch (Exception e) { Console.WriteLine($"即时通讯API Ping异常:{e.Message}"); } } // ReSharper disable once FunctionNeverReturns } /// /// 获取数据 /// /// /// public string GetData(string key) { var http = new HttpHelper(); var html = http.GetHtml($"http://{this._host}/api/TransferData/Get?key={key}&rd={DateTime.Now.Ticks}").Html; var rest = JObject.Parse(html); //if (!(rest["Ok"] ?? false).Value() throw new Exception(html); //return (rest["Data"] ?? string.Empty).Value(); //EventClient.OnEvent($"获取淘客域名数据", $"{html}"); if (!(rest["Ok"] ?? false).Value()) throw new Exception(html); return (rest["Data"] ?? string.Empty).Value(); } } }