using System.Drawing; using System.Drawing.Imaging; using System.Net.WebSockets; using System.Text; using Dm; using Masuit.Tools.Systems; using MoYu.DataEncryption; using MoYu.RemoteRequest.Extensions; using MoYu.Templates; using NewLife.Caching; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using SafeCampus.Application.Services.Business.AttendanceService; using SafeCampus.Application.Services.Business.ClassRoomCallService; using SafeCampus.Application.Services.Business.Warn.Dto; using SafeCampus.Application.Services.Business.Warn.Service; using SafeCampus.Core.Utils.TXYSMS; using TencentCloud.Nlp.V20190408.Models; namespace SafeCampus.Application.Manager.DeepelephManager; /// /// 深象智能对接实现 /// public class DeepelephManager : IDeepelephManager, IScoped { private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private bool _isConnected = false; private Timer _pingTimer; private List webScokets=new List(); private readonly ISimpleCacheService _simpleCacheService; public DeepelephManager(ISimpleCacheService simpleCacheService) { _simpleCacheService = simpleCacheService; } //获取地址 //建立请求,发送订阅参数 //遍历等待接收消息 public string GetToken() { var cacheToken = _simpleCacheService.Get(AuthConstants.SXTOKEN); if (cacheToken != null) return cacheToken; return GenSXToken(); } /// /// 获取深象智能Token /// /// private string GenSXToken() { var token = ""; var setting = App.GetOptionsMonitor(); var nonce = Guid.NewGuid().ToString("N"); var timestamp =DateTimeOffset.Now.ToUnixTimeMilliseconds(); var list = $"{setting.SXAPIURL}/user/center/v1/login/client" .SetBody(new { appKey = setting.AppKey, appSecret = setting.AppSecret, nonce , timestamp, sign = MD5Encryption.Encrypt($"{setting.AppSecret}appKey{setting.AppKey}nonce{nonce}timestamp{timestamp}{setting.AppSecret}",true) }) .SetContentType("application/json") .PostAsAsync().Result; var model = JsonConvert.DeserializeObject(list); if (model["success"]!=null) { if ((bool)model["success"]) { token = model["data"]["token"].ToString(); //token有效期2小时,提前20分钟失效 _simpleCacheService.Set(AuthConstants.SXTOKEN, token, 100*60); } else { LogHelper.WriteToLog("token请求失败", model["message"].ToString()); } } return token; } /// /// 订阅预警更新 /// /// public async Task SubscribeAlarm() { var setting = App.GetOptionsMonitor(); var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var url = GetWebSocketUrl(AuthConstants.SXALARM, AuthConstants.SXALARM_Grpup); var subscribeJson = JsonConvert.SerializeObject(new { token = GetToken(), type = "subscribe", timestamp, payload = new { topic = AuthConstants.SXALARM, consumerGroup = AuthConstants.SXALARM_Grpup, tags = setting.TenantCode } }); ClientWebSocket _webSocket = new ClientWebSocket(); webScokets.Add(_webSocket); await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None); //LogHelper.WriteToLog($"预警WebSocket 地址:{url}"); await _webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(subscribeJson)), WebSocketMessageType.Text, true, CancellationToken.None); byte[] buffer = new byte[1024*8]; while (_webSocket.State == WebSocketState.Open) { //try //{ // var jsonstr = // "{\"body\":{\"extend\":\"{\\\"trackId\\\":\\\"7173252404809024768\\\",\\\"genderScore\\\":[0.0,1.0,0.0],\\\"faceSnapshot\\\":\\\"http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/acp/quanjiang/DEMO00001/20240719/edge/group/SXT001_book_wm_1721360996798_55.jpg?Expires=1721368200&OSSAccessKeyId=STS.NSwBDiH7ZnNGS9m2ahE8XyuW6&Signature=dEBXyrWcz3FyXMqDueIkZL%2F9uhk%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5DCCf7dpeh72YysUR%2Fc1mE9Sbd0lrD81Dz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY4zJySB7g0s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxKTpyjlP%2FAxd8uAx9DyyfH1x3TObqd7jjqzaKs3NYdtswV4BUlvK5CGWEjhzQEO8mJtNIDT39ay%2BVK8NrfsIeBqAATzzKDWbI1DbvfIwuHS6%2BX5i%2FQ0%2BgbpA87Kw%2BQiZxZdvjHXLLqQaYmTRXkuFPxUqNR8BckkEiPPkSs%2B9UQm3Cwq6rnEFeZty8FvEKds5Wo3H2QevhGwkKNImDp%2BmIjF2gzxOSfDv5rBvJWanWW0ewZdlFeiIR88SRvtr10jyoV4OIAA%3D\\\",\\\"faceSnapshotPath\\\":\\\"deepvision:acp/quanjiang/DEMO00001/20240719/edge/group/SXT001_book_wm_1721360996798_55.jpg\\\",\\\"faceScore\\\":30.105469}\",\"alarmType\":\"mask_detect\",\"func\":\"mask_detect\",\"cameraId\":\"SXT001\",\"alarmId\":\"1600d5874d854f1da54e663ae56c845f\",\"snapshotUrl\":\"http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/acp/quanjiang/DEMO00001/20240719/edge/group/SXT001/SXT001_69bde610-a957-434b-a7ce-834aee148b2b_wm_56.jpg?Expires=1721368200&OSSAccessKeyId=STS.NSwBDiH7ZnNGS9m2ahE8XyuW6&Signature=hb6DQLWwZqukNQdel0TsUctAwAE%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5DCCf7dpeh72YysUR%2Fc1mE9Sbd0lrD81Dz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY4zJySB7g0s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxKTpyjlP%2FAxd8uAx9DyyfH1x3TObqd7jjqzaKs3NYdtswV4BUlvK5CGWEjhzQEO8mJtNIDT39ay%2BVK8NrfsIeBqAATzzKDWbI1DbvfIwuHS6%2BX5i%2FQ0%2BgbpA87Kw%2BQiZxZdvjHXLLqQaYmTRXkuFPxUqNR8BckkEiPPkSs%2B9UQm3Cwq6rnEFeZty8FvEKds5Wo3H2QevhGwkKNImDp%2BmIjF2gzxOSfDv5rBvJWanWW0ewZdlFeiIR88SRvtr10jyoV4OIAA%3D\",\"rects\":[{\"top\":601,\"left\":1156,\"width\":235,\"height\":767}],\"poiId\":\"DEMO00001\",\"tenantCode\":\"quanjiang\",\"tick\":1721360953398},\"bornTimestamp\":1721361000758,\"consumerGroup\":\"GID_quanjiang_risk\",\"keys\":\"1600d5874d854f1da54e663ae56c845f\",\"messageId\":\"AC14058A00017A07C5B45F3C813680EC\",\"queueId\":4,\"queueOffset\":422853,\"tags\":\"quanjiang\",\"topic\":\"ECOLOGY_PAAS_RISK_ALARM\",\"type\":\"msg\"}"; // var json = JsonConvert.DeserializeObject(jsonstr); // if (json["type"].ToString() == "msg") // { // var body = json["body"]; // if (body != null) // { // PersonType personEnum; // if (!Enum.TryParse(body["alarmType"].ToString(), out AlarmType dayEnum)) // { // dayEnum = AlarmType.visual_fence; // } // if (body["extend"] != null) // { // var extend = JsonConvert.DeserializeObject(body["extend"].ToString()); // if (extend["personType"] != null) // { // if (!Enum.TryParse(body["extend"]?["personType"]?.ToString(), out personEnum)) // { // personEnum = PersonType.unkonwn; // } // } // else // { // personEnum = PersonType.unkonwn; // } // } // else // { // personEnum = PersonType.unkonwn; // } // var model = new WarnInfoDto // { // TenantCode = body["tenantCode"]?.ToString(), // PoiId = body["poiId"]?.ToString(), // AlarmId = body["alarmId"]?.ToString(), // AlarmType = body["alarmType"]?.ToString(), // AlarmTypeDesc = dayEnum.GetDescription(), // CameraId = body["cameraId"]?.ToString(), // Tick = TimestampToDateTime(body["tick"].ToString()), // SnapshotUrl = body["snapshotUrl"]?.ToString(), // Rects = body["rects"]?.ToString(), // Tags = body["tags"]?.ToString(), // Extend = body["extend"]?.ToString(), // PersonType = personEnum.GetDescription(), // WarnHand = 0, // }; // var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], model.AlarmId + ".jpg"); // var steam = await model.SnapshotUrl.GetAsByteArrayAsync(); // model.SnapshotUrl = $"http://192.168.10.186:8003/Files/alarmImg/{model.AlarmId}.jpg"; // using (MemoryStream ms = new MemoryStream(steam)) // { // using (Bitmap bmp = new Bitmap(ms)) // { // using (Graphics g = Graphics.FromImage(bmp)) // { // using (Pen pen = new Pen(Color.Red, 3)) // { // foreach (var item in body["rects"]) // { // Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]); // g.DrawRectangle(pen, rect); // } // } // } // bmp.Save(signImg, ImageFormat.Jpeg); // } // } // //await model.SnapshotUrl.GetToSaveAsync(signImg); // Scoped.Create((_, scope) => // { // var services = scope.ServiceProvider; // var _repository = services.GetService(); // _repository.Add(model); // }); // } // } //} //catch (Exception e) //{ //} WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Text) { try { string message = Encoding.UTF8.GetString(buffer, 0, result.Count); var json = JsonConvert.DeserializeObject(message); if (json["type"].ToString() == "msg") { //TODO 发送短信 //TxySmsUtil.SendSms(new[] { "" }, new[] { "" }); var body = json["body"]; if (body != null) { PersonType personEnum; if (!Enum.TryParse(body["alarmType"].ToString(), out AlarmType dayEnum)) { dayEnum = AlarmType.visual_fence; } if (body["extend"] != null) { var extend = JsonConvert.DeserializeObject(body["extend"].ToString()); if (extend["personType"] != null) { if (!Enum.TryParse(body["extend"]?["personType"]?.ToString(), out personEnum)) { personEnum = PersonType.unkonwn; } } else { personEnum = PersonType.unkonwn; } } else { personEnum = PersonType.unkonwn; } var model = new WarnInfoDto { TenantCode = body["tenantCode"]?.ToString(), PoiId = body["poiId"]?.ToString(), AlarmId = body["alarmId"]?.ToString(), AlarmType = body["alarmType"]?.ToString(), AlarmTypeDesc = dayEnum.GetDescription(), CameraId = body["cameraId"]?.ToString(), Tick = TimestampToDateTime(body["tick"].ToString()), SnapshotUrl = body["snapshotUrl"]?.ToString(), Rects = body["rects"]?.ToString(), Tags = body["tags"]?.ToString(), Extend = body["extend"]?.ToString(), PersonType = personEnum.GetDescription(), WarnHand = 0, }; var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], model.AlarmId + ".jpg"); var steam = await model.SnapshotUrl.GetAsByteArrayAsync(); model.SnapshotUrl = $"http://192.168.10.186:8003/Files/alarmImg/{model.AlarmId}.jpg"; using (MemoryStream ms = new MemoryStream(steam)) { using (Bitmap bmp = new Bitmap(ms)) { using (Graphics g = Graphics.FromImage(bmp)) { using (Pen pen = new Pen(Color.Red, 3)) { foreach (var item in body["rects"]) { Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]); g.DrawRectangle(pen, rect); } } } bmp.Save(signImg, ImageFormat.Jpeg); } } Scoped.Create((_, scope) => { var services = scope.ServiceProvider; var _repository = services.GetService(); _repository.Add(model); }); } } else if (json["type"].ToString() == "cmd") { if ((bool)json["success"]) { if (json["message"].ToString().Contains("connect success")) { LogHelper.WriteToLog("预警连接成功"); } else if (json["message"].ToString().Contains("subscribe success")) { LogHelper.WriteToLog("预警订阅成功"); } } } } catch (Exception e) { LogHelper.WriteToLog($"收到: {Encoding.UTF8.GetString(buffer, 0, result.Count)}"); LogHelper.WriteToLog("预警webSocket处理异常"); LogHelper.WriteToLog(e, "预警webSocket处理异常"); } } else if (result.MessageType == WebSocketMessageType.Close) { LogHelper.WriteToLog("WebSocket 连接已被服务器关闭"); break; } } LogHelper.WriteToLog("预警webSocket关闭"); } /// /// 订阅点名事件 /// /// public async Task SubscriberRoomCall() { var setting = App.GetOptionsMonitor(); var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var url = GetWebSocketUrl(AuthConstants.SXROOM_CALL, AuthConstants.SXROOM_CAL_Group); var subscribeJson = JsonConvert.SerializeObject(new { token = GetToken(), type = "subscribe", timestamp, payload = new { topic = AuthConstants.SXROOM_CALL, consumerGroup = AuthConstants.SXROOM_CAL_Group, tags = setting.TenantCode } }); ClientWebSocket _webSocket = new ClientWebSocket(); webScokets.Add(_webSocket); await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None); //LogHelper.WriteToLog($"点名WebSocket 地址:{url}"); await _webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(subscribeJson)), WebSocketMessageType.Text, true, CancellationToken.None); byte[] buffer = new byte[1024*8]; while (_webSocket.State == WebSocketState.Open) { WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Text) { try { string message = Encoding.UTF8.GetString(buffer, 0, result.Count); //LogHelper.WriteToLog($"收到: {message}"); var json = JsonConvert.DeserializeObject(message); if (json["type"].ToString() == "msg") { var body = json["body"]; if (body != null) { //TODO 发送短信 //TxySmsUtil.SendSms(new[] { "" }, new[] { "" }); //TODO 由于未知道数据格式暂不写处理 if (!Enum.TryParse(body["alarmType"].ToString(), out AlarmType dayEnum)) { dayEnum = AlarmType.class_room_call; } var model = new ClassRoomCallDto { TenantCode = body["tenantCode"]?.ToString(), PoiId = body["poiId"]?.ToString(), TaskId = body["taskId"]?.ToString(), AlarmType = body["alarmType"].ToString(), AlarmTypeDesc = dayEnum.GetDescription(), EventId = body["eventId"]?.ToString(), CameraId = body["cameraId"]?.ToString(), Tick = TimestampToDateTime(body["tick"]?.ToString()), PersonSetId = body["personSetId"]?.ToString(), PersonId = body["personId"]?.ToString(), Similarity = body["similarity"] != null ? (float)body["similarity"] : 0, FaceScore = body["faceScore"] != null ? (float)body["faceScore"] : 0, SnapshotUrl = body["snapshotUrl"]?.ToString(), SnapshotData = body["snapshotData"]?.ToString(), Rects = body["rects"]?.ToString(), Extend = body["extend"]?.ToString(), CreateTime = DateTime.Now, TrackId = body["TrackId"]?.ToString() }; var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], model.EventId + ".jpg"); var steam = await model.SnapshotUrl.GetAsByteArrayAsync(); model.SnapshotUrl = $"http://192.168.10.186:8003/Files/roomCallImg/{model.EventId}.jpg"; using (MemoryStream ms = new MemoryStream(steam)) { using (Bitmap bmp = new Bitmap(ms)) { using (Graphics g = Graphics.FromImage(bmp)) { using (Pen pen = new Pen(Color.Red, 3)) { foreach (var item in body["rects"]) { Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]); g.DrawRectangle(pen, rect); } } } bmp.Save(signImg, ImageFormat.Jpeg); } } Scoped.Create((_, scope) => { var services = scope.ServiceProvider; var _repository = services.GetService(); _repository.Add(model); }); } } else if (json["type"].ToString() == "cmd") { if ((bool)json["success"]) { if (json["message"].ToString().Contains("connect success")) { LogHelper.WriteToLog("点名连接成功"); } else if (json["message"].ToString().Contains("subscribe success")) { LogHelper.WriteToLog("点名订阅成功"); } } } } catch (Exception e) { LogHelper.WriteToLog($"收到: {Encoding.UTF8.GetString(buffer, 0, result.Count)}"); LogHelper.WriteToLog("点名webSocket处理异常"); LogHelper.WriteToLog(e, "点名webSocket处理异常"); } } else if (result.MessageType == WebSocketMessageType.Close) { LogHelper.WriteToLog("点名WebSocket 连接已被服务器关闭"); break; } } LogHelper.WriteToLog("点名webSocket已关闭"); } public async Task SubscriberAttendance() { var setting = App.GetOptionsMonitor(); var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var url = GetWebSocketUrl(AuthConstants.SXECOLOGY_ATTENDANCE, AuthConstants.SXECOLOGY_ATTENDANCE_Group); var subscribeJson = JsonConvert.SerializeObject(new { token = GetToken(), type = "subscribe", timestamp, payload = new { topic = AuthConstants.SXECOLOGY_ATTENDANCE, consumerGroup = AuthConstants.SXECOLOGY_ATTENDANCE_Group, tags = setting.TenantCode } }); ClientWebSocket _webSocket = new ClientWebSocket(); webScokets.Add(_webSocket); await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None); //LogHelper.WriteToLog($"考勤WebSocket 已连接:{url}"); await _webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(subscribeJson)), WebSocketMessageType.Text, true, CancellationToken.None); byte[] buffer = new byte[1024 * 8]; while (_webSocket.State == WebSocketState.Open) { WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Text) { try { string message = Encoding.UTF8.GetString(buffer, 0, result.Count); //LogHelper.WriteToLog($"收到: {message}"); var json = JsonConvert.DeserializeObject(message); if (json["type"].ToString() == "msg") { var body = json["body"]; if (body != null) { //TODO 发送短信 //TxySmsUtil.SendSms(new[] { "" }, new[] { "" }); //TODO 由于未知道数据格式暂不写处理 var model = new AttendanceDto() { TenantCode = body["tenantCode"]?.ToString(), PoiId = body["poiId"]?.ToString(), EventId = body["eventId"]?.ToString(), CameraId = body["cameraId"]?.ToString(), Tick = TimestampToDateTime(body["tick"]?.ToString()), PersonSetId = body["personSetId"]?.ToString(), PersonId = body["personId"]?.ToString(), Similarity = body["similarity"] != null ? (float)body["similarity"] : 0, FaceScore = body["faceScore"] != null ? (float)body["faceScore"] : 0, SnapshotUrl = body["snapshotUrl"]?.ToString(), SnapshotData = body["snapshotData"]?.ToString(), Rects = body["rects"]?.ToString(), Extend = body["extend"]?.ToString(), CreateTime = DateTime.Now, TrackId = body["TrackId"]?.ToString(), }; var signImg = Path.Combine(Directory.GetCurrentDirectory(), "Files", App.Configuration["AppInfo:AlarmImg"], model.EventId + ".jpg"); var steam = await model.SnapshotUrl.GetAsByteArrayAsync(); model.SnapshotUrl = $"http://192.168.10.186:8003/Files/attendanceImg/{model.EventId}.jpg"; using (MemoryStream ms = new MemoryStream(steam)) { using (Bitmap bmp = new Bitmap(ms)) { using (Graphics g = Graphics.FromImage(bmp)) { using (Pen pen = new Pen(Color.Red, 3)) { foreach (var item in body["rects"]) { Rectangle rect = new Rectangle((int)item["left"], (int)item["top"], (int)item["width"], (int)item["height"]); g.DrawRectangle(pen, rect); } } } bmp.Save(signImg, ImageFormat.Jpeg); } } Scoped.Create((_, scope) => { var services = scope.ServiceProvider; var repository = services.GetService(); repository.Add(model); }); } }else if (json["type"].ToString()=="cmd") { if ((bool)json["success"]) { if (json["message"].ToString().Contains("connect success")) { LogHelper.WriteToLog("考勤连接成功"); }else if (json["message"].ToString().Contains("subscribe success")) { LogHelper.WriteToLog("考勤订阅成功"); } } } } catch (Exception e) { LogHelper.WriteToLog($"收到: {Encoding.UTF8.GetString(buffer, 0, result.Count)}"); LogHelper.WriteToLog("考勤webSocket处理异常"); LogHelper.WriteToLog(e, "考勤webSocket处理异常"); } } else if (result.MessageType == WebSocketMessageType.Close) { LogHelper.WriteToLog("考勤WebSocket 连接已被服务器关闭"); break; } } LogHelper.WriteToLog("考勤webSocket已关闭"); } private async Task GetWebSocketData(string url, string json) { ClientWebSocket _webSocket = new ClientWebSocket(); while (!_cancellationTokenSource.IsCancellationRequested) { try { await _webSocket.ConnectAsync(new Uri(url), CancellationToken.None); LogHelper.WriteToLog("WebSocket 已连接"); _isConnected = true; //订阅预警消息 await _webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(json)), WebSocketMessageType.Text, true, CancellationToken.None); //_pingTimer = new Timer(async (state) => //{ // if (_webSocket.State == WebSocketState.Open) // { // try // { // LogHelper.WriteToLog("发送 ping..."); // byte[] emptyPingMessage = Array.Empty(); // await _webSocket.SendAsync(new ArraySegment(emptyPingMessage), WebSocketMessageType.Binary, true, CancellationToken.None); // //byte[] pingMessage = Encoding.UTF8.GetBytes("pong"); // //await _webSocket.SendAsync(new ArraySegment(pingMessage), WebSocketMessageType.Text, true, CancellationToken.None); // } // catch (Exception ex) // { // LogHelper.WriteToLog($"发送ping失败: {ex.Message}"); // } // } //}, null, TimeSpan.Zero, TimeSpan.FromSeconds(30)); await ReceiveLoop(_webSocket); _isConnected = false; LogHelper.WriteToLog("WebSocket 连接已关闭,正在重连。。。"); } catch (Exception ex) { LogHelper.WriteToLog($"WebSocket连接失败: {ex.Message}"); } await Task.Delay(GetReconnectInterval()); } } private async Task ReceiveLoop(ClientWebSocket _webSocket) { byte[] buffer = new byte[1024]; while (_webSocket.State == WebSocketState.Open) { WebSocketReceiveResult result = await _webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Text) { string message = Encoding.UTF8.GetString(buffer, 0, result.Count); LogHelper.WriteToLog($"收到: {message}"); var json= JsonConvert.DeserializeObject(message); if (json["type"].ToString()=="msg") { var body = json["body"]; if (body!=null) { } } } else if (result.MessageType == WebSocketMessageType.Close) { LogHelper.WriteToLog("WebSocket 连接已被服务器关闭"); break; } } } private TimeSpan GetReconnectInterval() { // You can implement your own logic for calculating reconnect interval, e.g., exponential backoff return TimeSpan.FromSeconds(10); // Example: Attempt to reconnect every 10 seconds } public async Task DisconnectAsync() { foreach (var clientWebSocket in webScokets.Where(clientWebSocket => clientWebSocket.State == WebSocketState.Open)) { await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); } } private string GetWebSocketUrl(string topic, string consumerGroup) { var serverAddr = ""; var setting = App.GetOptionsMonitor(); var list = $"{setting.SXAPIURL}/emitter/connection/get" .SetBody(new { token = GetToken(), topic , consumerGroup, }) .SetContentType("application/json") .PostAsAsync().Result; var model = JsonConvert.DeserializeObject(list); if (model["data"]["serverAddr"]!=null) { serverAddr = model["data"]["serverAddr"].ToString(); } return serverAddr; } //public async Task GetData() //{ // //var setting = App.GetOptionsMonitor(); // //var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // ////订阅预警消息 // //var warnUrl = GetWebSocketUrl(AuthConstants.SXALARM, AuthConstants.SXALARM_Grpup); // //GetWebSocketData(warnUrl, // // JsonConvert.SerializeObject(new // // { // // token = GetToken(), type = "subscribe", timestamp, // // payload = new { topic = AuthConstants.SXALARM, consumerGroup= AuthConstants.SXALARM_Grpup, tags= setting.TenantCode } // // })); // //订阅预警更新消息 // await SubscribeAlarm(); // //订阅点名事件 // //await SubscriberRoomCall(); // return true; //} /// /// 时间戳转本时区日期时间 /// /// /// public static DateTime TimestampToDateTime(string timeStamp) { DateTimeOffset utcDateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(timeStamp)); return utcDateTimeOffset.LocalDateTime; } }