old_flsystem/类库/Api.Framework/NoticeSocketClient.cs

199 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 通知客户端
/// </summary>
public class NoticeSocketClient
{
/// <summary>
/// 发送Ack模式通知数据
/// </summary>
public class AckNoticeData : EventArgs
{
/// <summary>
/// ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 命令ID
/// </summary>
public string CommonId { get; set; }
/// <summary>
/// 信号道
/// </summary>
public string Channel { get; set; }
/// <summary>
/// 数据
/// </summary>
public string Data { get; set; }
/// <summary>
/// 生成时间
/// </summary>
public DateTime CreateDateTime { get; set; }
/// <summary>
/// 标记被删除
/// </summary>
public bool IsRemove { get; set; }
/// <summary>
/// 重试
/// </summary>
public bool IsRetry { get; set; }
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="host"></param>
/// <param name="channel"></param>
public NoticeSocketClient(string host, params string[] channel)
{
this._host = host;
this._channels = channel.ToArray();
}
private readonly string[] _channels;
private readonly string _host;
/// <summary>
/// 连接对象
/// </summary>
private WebSocket _websocket;
/// <summary>
/// 连接状态
/// </summary>
public bool IsConnected => (_websocket != null && _websocket.IsAlive);
/// <summary>
/// 连接
/// </summary>
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();
}
}
/// <summary>
/// 收到消息事件
/// </summary>
public event EventHandler<AckNoticeData> OnMessageEvent;
/// <summary>
/// 连接成功事件
/// </summary>
public event EventHandler<EventArgs> 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<AckNoticeData>(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
}
/// <summary>
/// 获取数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
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<bool>() throw new Exception(html);
//return (rest["Data"] ?? string.Empty).Value<string>();
//EventClient.OnEvent($"获取淘客域名数据", $"{html}");
if (!(rest["Ok"] ?? false).Value<bool>())
throw new Exception(html);
return (rest["Data"] ?? string.Empty).Value<string>();
}
}
}