using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Threading; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Transports; using MY.BllModel; using Newtonsoft.Json; using Task = System.Threading.Tasks.Task; using MY.Logging; using MY.Utility; namespace SignalR.Persistent { /// <summary> /// 持久连接 /// </summary> public partial class CharPersistent : PersistentConnection { //log类声明为局部静态是为性能考虑 private static readonly LogHelper LogHelper = new LogHelper("SignalR.Persistent.CharPersistent"); protected static SyncList<DeviceOnlineModel> UserModelList = new SyncList<DeviceOnlineModel>(); /// <summary> /// 真实链接数量 /// </summary> protected static int ConnectionsCount = 0; /// <summary> /// 接受到消息 /// </summary> protected override async Task OnReceived(IRequest request, string connectionId, string data) { try { if (string.IsNullOrEmpty(data)) { throw new Exception("请求参数不能为空"); } var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(data); if (!json.ContainsKey("type") || !json.ContainsKey("text")) { throw new Exception("参数{type,text}不能为空"); } switch (json["type"].ToString().ToLower()) { case "online": //设备、web上线 await Online(request, connectionId, json["text"].ToString()); break; case "ng": //设备、web指令接收 await MsgForwarding(connectionId, data); if (json["text"].ToString().ToLower() == "getall") { LogHelper.DebugAsync("设备返回getall时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")); } break; case "onlineline": //获得在线列表 Connection.SendToWeb(connectionId, new {count = ConnectionsCount, list = UserModelList}.ToJson()); break; case "sendmsg": //中转服务器发送消息 ServiceSendMsg(json["userid"].ToString(), json["text"].ToString()); break; case "appexceptionlog": //应用异常日志 AddException(json["text"].ToString()); break; case "recovered": //找回设备 case "notice": //通知回复 case "getbluetooth": //取的蓝牙数据 case "getappblacklist": //取的应用黑名单数据 case "getphonebook": //取的电话簿 case "removeapp": //删除app if (json["result"].ToString() == "1") { HandlePushEnd(json["text"].ToString()); LogHelper.DebugAsync(string.Format("特殊推送收到成功回复,回复类型:{0},json:{1}", json["type"].ToString().ToLower(), data)); } else { LogHelper.DebugAsync(string.Format("特殊推送收到失败回复,回复类型:{0},json:{1}", json["type"].ToString().ToLower(), data)); } break; default: LogHelper.DebugAsync(string.Format("服务器接收到消息【{0}】,消息内容为{1}", connectionId, data)); break; } } catch (Exception ex) { LogHelper.ErrorAsync("接收消息异常:" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message)); //错误指令返回 Connection.SendErrMsg(connectionId, ex.Message); } } /// <summary> /// 用户发送消息转发处理 /// </summary> /// <param name="userid"></param> /// <param name="msg"></param> private void ServiceSendMsg(string userid, string msg) { if (string.IsNullOrEmpty(userid)) { return; } userid = Uri.EscapeDataString(userid); var entity = UserModelList.FirstOrDefaultV(q => q.UserId == userid && q.UserType == (int) UserType.AppUser); if (entity != null) { //指定用户发送消息 Connection.Send(entity.UserConnerctionId, msg); } LogHelper.DebugAsync(string.Format("服务推送消息给设备用户【{0}】,消息内容为{1}", userid, msg)); } /// <summary> /// 上线 /// </summary> /// <param name="request"></param> /// <param name="connectionId"></param> /// <param name="text"></param> private async Task Online(IRequest request, string connectionId, string text = "") { try { //获得用户信息 if (string.IsNullOrEmpty(text)) { text = request.QueryString["userid"]; if (string.IsNullOrEmpty(text)) { return; } } if (string.IsNullOrEmpty(text)) { throw new Exception("参数{text}不能为空"); } var texts = text.Split(‘|‘); if (texts.Length < 2) { throw new Exception("参数{text}异常:{\"type\":\"online\",\"text\":\"imei|usertype|sign|timestamp\"}"); } var userid = texts[0]; //用户 var usertype = 0; if (!int.TryParse(texts[1], out usertype)) { throw new Exception( "参数{text}异常:{\"type\":\"online\",\"text\":\"imei|usertype|sign|timestamp\"},usertype参数异常"); } //存储用户 var model = UserModelList.FirstOrDefaultV(q => q.UserConnerctionId == connectionId); if (model == null) { userid = Uri.EscapeDataString(userid); UserModelList.Add(new DeviceOnlineModel() {UserConnerctionId = connectionId, UserId = userid, UserType = usertype}); } //web上线 if (usertype == (int) UserType.SysWebUser) { //验证请求地址是否合法 var hosts = ConfigurationManager.AppSettings["SignalRClientWebHost"]; if (!string.IsNullOrEmpty(hosts)) { var arrHost = hosts.Split(‘,‘); var origin = request.Headers["Origin"]; //非法地址直接断开 if (!arrHost.Contains(origin)) { LogHelper.ErrorAsync("非法连接,请求来源:" + request.Headers.ToJson() + ",连接数据:" + text); await ServiceDisconnect(connectionId); return; } } //获得要发送的链接id列表 var sendEntity = GetRrelatedSendList(connectionId).FirstOrDefault(); if (sendEntity != null) { //记录日志 LogHelper.DebugAsync("WEB用户getall时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")); //推送获取设备信息指令 await Task.Run(() => Connection.SendToDevice(sendEntity.UserConnerctionId, JsonConvert.SerializeObject(new {type = "ng", text = "getall",}))); //告知web该设备在线 //await Task.Run(() => Connection.SendToWeb(connectionId, "Online")); } else { //告知web该设备不在线 await Task.Run(() => Connection.SendToWeb(connectionId, "NoOnline")); } //记录日志 LogHelper.DebugAsync("WEB用户【" + Uri.UnescapeDataString(userid) + "】上线了"); } //设备上线 else { //验证请求是否合法 if (texts.Length != 4) { throw new Exception( "参数{text}异常:{\"type\":\"online\",\"text\":\"imei|usertype|sign|timestamp\"}"); } //检测是否合法 var signalRKey = ConfigurationManager.AppSettings["SignalRKey"]; if (signalRKey != "") { var sign = texts[2]; var timestamp = texts[3]; var sign2 = MY.Utility.Encryption.EncryptMd5($"{userid}|{usertype}|{timestamp}|{signalRKey}"); if (!sign.Equals(sign2, StringComparison.OrdinalIgnoreCase)) { LogHelper.ErrorAsync("非法连接 ,连接数据:" + text); await ServiceDisconnect(connectionId); return; } } //存在网站用户登陆 bool onlineCnt = UserModelList.AnyV(o => o.UserId == userid && o.UserType == (int) UserType.SysWebUser); if (onlineCnt) { //推送获取设备信息指令 await Task.Run(() => Connection.SendToDevice(connectionId, JsonConvert.SerializeObject(new {type = "ng", text = "getall",}))); } //记录日志 LogHelper.DebugAsync("设备用户【" + Uri.UnescapeDataString(text) + "】上线了"); //同步设备在线情况 SyncDeviceOnlineSituation(); //写入设备上线记录 AddDeviceConnectLog(userid, connectionId, 1, "设备上线"); } } catch (Exception e) { LogHelper.ErrorAsync("连接上线异常【" + text + "】:" + (e.InnerException != null ? e.InnerException.Message : e.Message)); LogHelper.ErrorAsync("异常堆栈:" + e.ToJson()); //错误指令返回 Connection.SendErrMsg(connectionId, e.Message); ServiceDisconnect(connectionId, false); } } /// <summary> /// 连接断开 /// </summary> protected override async Task OnDisconnected(IRequest request, string connectionId, bool stopCalled) { Interlocked.Decrement(ref ConnectionsCount); try { DeviceOnlineModel model = UserModelList.FirstOrDefaultV(q => q.UserConnerctionId == connectionId); if (model != null) { //设备离线 if (model.UserType == (int) UserType.AppUser) { var sendEntitys = GetRrelatedSendList(connectionId); if (sendEntitys != null) { foreach (var sendEntity in sendEntitys) { List<DeviceOnlineModel> onlineList = UserModelList.WhereV(o => o.UserId == model.UserId && o.UserType == (int) UserType.AppUser).ToList(); if (onlineList.Count() == 1) { //推送设备离线 await Task.Run(() => Connection.SendToWeb(sendEntity.UserConnerctionId, "NoOnline")); } } } LogHelper.DebugAsync("设备用户【" + Uri.UnescapeDataString(model.UserId + "|" + model.UserType) + "】下线了"); #pragma warning disable 4014 //同步设备在线情况 SyncDeviceOnlineSituation(); //写入设备下线记录 AddDeviceConnectLog(model.UserId, connectionId, 2, "设备下线"); #pragma warning restore 4014 } else { LogHelper.DebugAsync("WEB用户【" + Uri.UnescapeDataString(model.UserId + "|" + model.UserType) + "】下线了"); } UserModelList.Remove(model); } } catch (Exception e) { LogHelper.ErrorAsync("连接断开异常【" + connectionId + "】:" + (e.InnerException != null ? e.InnerException.Message : e.Message)); LogHelper.ErrorAsync("异常堆栈:" + e.ToJson()); } //默认调用 await base.OnDisconnected(request, connectionId, stopCalled); } /// <summary> /// 连接创建 /// </summary> protected override async Task OnConnected(IRequest request, string connectionId) { Interlocked.Increment(ref ConnectionsCount); //特定内部不需要上线直接发消息 if (request.QueryString["inner"] + "" == "yes") { await base.OnConnected(request, connectionId); return; } await Online(request, connectionId); await base.OnConnected(request, connectionId); } /// <summary> /// 重新连接 /// </summary> /// <param name="request"></param> /// <param name="connectionId"></param> /// <returns></returns> protected override async Task OnReconnected(IRequest request, string connectionId) { //ConnectionsCount++; await Online(request, connectionId); await base.OnReconnected(request, connectionId); } /// <summary> /// 消息转发,通过当前消息用户链接id找到对应的用户链接id /// </summary> /// <param name="userConnerctionId"></param> /// <param name="data"></param> private async Task MsgForwarding(string userConnerctionId, string data) { if (string.IsNullOrEmpty(userConnerctionId)) { return; } //获得要发送的链接id列表 var sendEntitys = GetRrelatedSendList(userConnerctionId); if (sendEntitys != null) { foreach (var model in sendEntitys) { if (model != null) { //指定用户发送消息 await Connection.Send(model.UserConnerctionId, data); LogHelper.DebugAsync($"服务器转发消息给用户:{model.UserId}|{model.UserType},内容为:{data}"); } } } //记录用户记录 DeviceOnlineModel entity = UserModelList.FirstOrDefaultV(o => o.UserConnerctionId == userConnerctionId); if (entity != null) { //指令发送成功后回复发送端发送成功 if (entity.UserType == (int) UserType.SysWebUser) { var dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(data); if (dic["text"].Equals("restart") || dic["text"].Equals("shutdown") || dic["text"].Equals("resumedefault")) { await Connection.Send(entity.UserConnerctionId, "MainSendOK"); } } LogHelper.DebugAsync("服务器接收到【" + (entity.UserType == (int) UserType.SysWebUser ? "WEB" : "设备") + "】用户【" + entity.UserId + "】,消息内容为:" + data); } } /// <summary> /// 获得发送连接id列表 /// </summary> /// <param name="userConnerctionId"></param> /// <returns></returns> public List<DeviceOnlineModel> GetRrelatedSendList(string userConnerctionId) { //发送消息的用户 var entity = UserModelList.FirstOrDefaultV(q => q.UserConnerctionId == userConnerctionId); if (entity != null) { var usertype = entity.UserType == (int) UserType.AppUser ? (int) UserType.SysWebUser : (int) UserType.AppUser; //要推送消息的用户 var sendEntitys = UserModelList.WhereV(q => q.UserId == entity.UserId && q.UserType == usertype) .ToList(); return sendEntitys; } return null; } /// <summary> /// 服务器强制断开连接 /// </summary> /// <param name="connectionId"></param> /// <param name="isSendErrMsg"></param> private async Task ServiceDisconnect(string connectionId, bool isSendErrMsg = true) { await GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections() .First(o => o.ConnectionId == connectionId).Disconnect(); if (isSendErrMsg) { //错误指令返回 Connection.SendErrMsg(connectionId, "非法连接,强制断开"); } } } }
| using System; | |
| using System.Collections.Generic; | |
| using System.Configuration; | |
| using System.Linq; | |
| using System.Threading; | |
| using Microsoft.AspNet.SignalR; | |
| using Microsoft.AspNet.SignalR.Transports; | |
| using MY.BllModel; | |
| using Newtonsoft.Json; | |
| using Task = System.Threading.Tasks.Task; | |
| using MY.Logging; | |
| using MY.Utility; | |
| namespace SignalR.Persistent | |
| { | |
| /// <summary> | |
| /// 持久连接 | |
| /// </summary> | |
| public partial class CharPersistent : PersistentConnection | |
| { | |
| //log类声明为局部静态是为性能考虑 | |
| private static readonly LogHelper LogHelper = new LogHelper("SignalR.Persistent.CharPersistent"); | |
| protected static SyncList<DeviceOnlineModel> UserModelList = new SyncList<DeviceOnlineModel>(); | |
| /// <summary> | |
| /// 真实链接数量 | |
| /// </summary> | |
| protected static int ConnectionsCount = 0; | |
| /// <summary> | |
| /// 接受到消息 | |
| /// </summary> | |
| protected override async Task OnReceived(IRequest request, string connectionId, string data) | |
| { | |
| try | |
| { | |
| if (string.IsNullOrEmpty(data)) | |
| { | |
| throw new Exception("请求参数不能为空"); | |
| } | |
| var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(data); | |
| if (!json.ContainsKey("type") || !json.ContainsKey("text")) | |
| { | |
| throw new Exception("参数{type,text}不能为空"); | |
| } | |
| switch (json["type"].ToString().ToLower()) | |
| { | |
| case "online": //设备、web上线 | |
| await Online(request, connectionId, json["text"].ToString()); | |
| break; | |
| case "ng": //设备、web指令接收 | |
| await MsgForwarding(connectionId, data); | |
| if (json["text"].ToString().ToLower() == "getall") | |
| { | |
| LogHelper.DebugAsync("设备返回getall时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")); | |
| } | |
| break; | |
| case "onlineline": //获得在线列表 | |
| Connection.SendToWeb(connectionId, | |
| new {count = ConnectionsCount, list = UserModelList}.ToJson()); | |
| break; | |
| case "sendmsg": //中转服务器发送消息 | |
| ServiceSendMsg(json["userid"].ToString(), json["text"].ToString()); | |
| break; | |
| case "appexceptionlog": //应用异常日志 | |
| AddException(json["text"].ToString()); | |
| break; | |
| case "recovered": //找回设备 | |
| case "notice": //通知回复 | |
| case "getbluetooth": //取的蓝牙数据 | |
| case "getappblacklist": //取的应用黑名单数据 | |
| case "getphonebook": //取的电话簿 | |
| case "removeapp": //删除app | |
| if (json["result"].ToString() == "1") | |
| { | |
| HandlePushEnd(json["text"].ToString()); | |
| LogHelper.DebugAsync(string.Format("特殊推送收到成功回复,回复类型:{0},json:{1}", | |
| json["type"].ToString().ToLower(), data)); | |
| } | |
| else | |
| { | |
| LogHelper.DebugAsync(string.Format("特殊推送收到失败回复,回复类型:{0},json:{1}", | |
| json["type"].ToString().ToLower(), data)); | |
| } | |
| break; | |
| default: | |
| LogHelper.DebugAsync(string.Format("服务器接收到消息【{0}】,消息内容为{1}", connectionId, data)); | |
| break; | |
| } | |
| } | |
| catch (Exception ex) | |
| { | |
| LogHelper.ErrorAsync("接收消息异常:" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message)); | |
| //错误指令返回 | |
| Connection.SendErrMsg(connectionId, ex.Message); | |
| } | |
| } | |
| /// <summary> | |
| /// 用户发送消息转发处理 | |
| /// </summary> | |
| /// <param name="userid"></param> | |
| /// <param name="msg"></param> | |
| private void ServiceSendMsg(string userid, string msg) | |
| { | |
| if (string.IsNullOrEmpty(userid)) | |
| { | |
| return; | |
| } | |
| userid = Uri.EscapeDataString(userid); | |
| var entity = UserModelList.FirstOrDefaultV(q => q.UserId == userid && q.UserType == (int) UserType.AppUser); | |
| if (entity != null) | |
| { | |
| //指定用户发送消息 | |
| Connection.Send(entity.UserConnerctionId, msg); | |
| } | |
| LogHelper.DebugAsync(string.Format("服务推送消息给设备用户【{0}】,消息内容为{1}", userid, msg)); | |
| } | |
| /// <summary> | |
| /// 上线 | |
| /// </summary> | |
| /// <param name="request"></param> | |
| /// <param name="connectionId"></param> | |
| /// <param name="text"></param> | |
| private async Task Online(IRequest request, string connectionId, string text = "") | |
| { | |
| try | |
| { | |
| //获得用户信息 | |
| if (string.IsNullOrEmpty(text)) | |
| { | |
| text = request.QueryString["userid"]; | |
| if (string.IsNullOrEmpty(text)) | |
| { | |
| return; | |
| } | |
| } | |
| if (string.IsNullOrEmpty(text)) | |
| { | |
| throw new Exception("参数{text}不能为空"); | |
| } | |
| var texts = text.Split(‘|‘); | |
| if (texts.Length < 2) | |
| { | |
| throw new Exception("参数{text}异常:{\"type\":\"online\",\"text\":\"imei|usertype|sign|timestamp\"}"); | |
| } | |
| var userid = texts[0]; //用户 | |
| var usertype = 0; | |
| if (!int.TryParse(texts[1], out usertype)) | |
| { | |
| throw new Exception( | |
| "参数{text}异常:{\"type\":\"online\",\"text\":\"imei|usertype|sign|timestamp\"},usertype参数异常"); | |
| } | |
| //存储用户 | |
| var model = UserModelList.FirstOrDefaultV(q => q.UserConnerctionId == connectionId); | |
| if (model == null) | |
| { | |
| userid = Uri.EscapeDataString(userid); | |
| UserModelList.Add(new DeviceOnlineModel() | |
| {UserConnerctionId = connectionId, UserId = userid, UserType = usertype}); | |
| } | |
| //web上线 | |
| if (usertype == (int) UserType.SysWebUser) | |
| { | |
| //验证请求地址是否合法 | |
| var hosts = ConfigurationManager.AppSettings["SignalRClientWebHost"]; | |
| if (!string.IsNullOrEmpty(hosts)) | |
| { | |
| var arrHost = hosts.Split(‘,‘); | |
| var origin = request.Headers["Origin"]; | |
| //非法地址直接断开 | |
| if (!arrHost.Contains(origin)) | |
| { | |
| LogHelper.ErrorAsync("非法连接,请求来源:" + request.Headers.ToJson() + ",连接数据:" + text); | |
| await ServiceDisconnect(connectionId); | |
| return; | |
| } | |
| } | |
| //获得要发送的链接id列表 | |
| var sendEntity = GetRrelatedSendList(connectionId).FirstOrDefault(); | |
| if (sendEntity != null) | |
| { | |
| //记录日志 | |
| LogHelper.DebugAsync("WEB用户getall时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")); | |
| //推送获取设备信息指令 | |
| await Task.Run(() => Connection.SendToDevice(sendEntity.UserConnerctionId, | |
| JsonConvert.SerializeObject(new {type = "ng", text = "getall",}))); | |
| //告知web该设备在线 | |
| //await Task.Run(() => Connection.SendToWeb(connectionId, "Online")); | |
| } | |
| else | |
| { | |
| //告知web该设备不在线 | |
| await Task.Run(() => Connection.SendToWeb(connectionId, "NoOnline")); | |
| } | |
| //记录日志 | |
| LogHelper.DebugAsync("WEB用户【" + Uri.UnescapeDataString(userid) + "】上线了"); | |
| } | |
| //设备上线 | |
| else | |
| { | |
| //验证请求是否合法 | |
| if (texts.Length != 4) | |
| { | |
| throw new Exception( | |
| "参数{text}异常:{\"type\":\"online\",\"text\":\"imei|usertype|sign|timestamp\"}"); | |
| } | |
| //检测是否合法 | |
| var signalRKey = ConfigurationManager.AppSettings["SignalRKey"]; | |
| if (signalRKey != "") | |
| { | |
| var sign = texts[2]; | |
| var timestamp = texts[3]; | |
| var sign2 = MY.Utility.Encryption.EncryptMd5($"{userid}|{usertype}|{timestamp}|{signalRKey}"); | |
| if (!sign.Equals(sign2, StringComparison.OrdinalIgnoreCase)) | |
| { | |
| LogHelper.ErrorAsync("非法连接 ,连接数据:" + text); | |
| await ServiceDisconnect(connectionId); | |
| return; | |
| } | |
| } | |
| //存在网站用户登陆 | |
| bool onlineCnt = | |
| UserModelList.AnyV(o => o.UserId == userid && o.UserType == (int) UserType.SysWebUser); | |
| if (onlineCnt) | |
| { | |
| //推送获取设备信息指令 | |
| await Task.Run(() => Connection.SendToDevice(connectionId, | |
| JsonConvert.SerializeObject(new {type = "ng", text = "getall",}))); | |
| } | |
| //记录日志 | |
| LogHelper.DebugAsync("设备用户【" + Uri.UnescapeDataString(text) + "】上线了"); | |
| //同步设备在线情况 | |
| SyncDeviceOnlineSituation(); | |
| //写入设备上线记录 | |
| AddDeviceConnectLog(userid, connectionId, 1, "设备上线"); | |
| } | |
| } | |
| catch (Exception e) | |
| { | |
| LogHelper.ErrorAsync("连接上线异常【" + text + "】:" + | |
| (e.InnerException != null ? e.InnerException.Message : e.Message)); | |
| LogHelper.ErrorAsync("异常堆栈:" + e.ToJson()); | |
| //错误指令返回 | |
| Connection.SendErrMsg(connectionId, e.Message); | |
| ServiceDisconnect(connectionId, false); | |
| } | |
| } | |
| /// <summary> | |
| /// 连接断开 | |
| /// </summary> | |
| protected override async Task OnDisconnected(IRequest request, string connectionId, bool stopCalled) | |
| { | |
| Interlocked.Decrement(ref ConnectionsCount); | |
| try | |
| { | |
| DeviceOnlineModel model = UserModelList.FirstOrDefaultV(q => q.UserConnerctionId == connectionId); | |
| if (model != null) | |
| { | |
| //设备离线 | |
| if (model.UserType == (int) UserType.AppUser) | |
| { | |
| var sendEntitys = GetRrelatedSendList(connectionId); | |
| if (sendEntitys != null) | |
| { | |
| foreach (var sendEntity in sendEntitys) | |
| { | |
| List<DeviceOnlineModel> onlineList = UserModelList.WhereV(o => | |
| o.UserId == model.UserId && o.UserType == (int) UserType.AppUser).ToList(); | |
| if (onlineList.Count() == 1) | |
| { | |
| //推送设备离线 | |
| await Task.Run(() => | |
| Connection.SendToWeb(sendEntity.UserConnerctionId, "NoOnline")); | |
| } | |
| } | |
| } | |
| LogHelper.DebugAsync("设备用户【" + Uri.UnescapeDataString(model.UserId + "|" + model.UserType) + | |
| "】下线了"); | |
| #pragma warning disable 4014 | |
| //同步设备在线情况 | |
| SyncDeviceOnlineSituation(); | |
| //写入设备下线记录 | |
| AddDeviceConnectLog(model.UserId, connectionId, 2, "设备下线"); | |
| #pragma warning restore 4014 | |
| } | |
| else | |
| { | |
| LogHelper.DebugAsync("WEB用户【" + Uri.UnescapeDataString(model.UserId + "|" + model.UserType) + | |
| "】下线了"); | |
| } | |
| UserModelList.Remove(model); | |
| } | |
| } | |
| catch (Exception e) | |
| { | |
| LogHelper.ErrorAsync("连接断开异常【" + connectionId + "】:" + | |
| (e.InnerException != null ? e.InnerException.Message : e.Message)); | |
| LogHelper.ErrorAsync("异常堆栈:" + e.ToJson()); | |
| } | |
| //默认调用 | |
| await base.OnDisconnected(request, connectionId, stopCalled); | |
| } | |
| /// <summary> | |
| /// 连接创建 | |
| /// </summary> | |
| protected override async Task OnConnected(IRequest request, string connectionId) | |
| { | |
| Interlocked.Increment(ref ConnectionsCount); | |
| //特定内部不需要上线直接发消息 | |
| if (request.QueryString["inner"] + "" == "yes") | |
| { | |
| await base.OnConnected(request, connectionId); | |
| return; | |
| } | |
| await Online(request, connectionId); | |
| await base.OnConnected(request, connectionId); | |
| } | |
| /// <summary> | |
| /// 重新连接 | |
| /// </summary> | |
| /// <param name="request"></param> | |
| /// <param name="connectionId"></param> | |
| /// <returns></returns> | |
| protected override async Task OnReconnected(IRequest request, string connectionId) | |
| { | |
| //ConnectionsCount++; | |
| await Online(request, connectionId); | |
| await base.OnReconnected(request, connectionId); | |
| } | |
| /// <summary> | |
| /// 消息转发,通过当前消息用户链接id找到对应的用户链接id | |
| /// </summary> | |
| /// <param name="userConnerctionId"></param> | |
| /// <param name="data"></param> | |
| private async Task MsgForwarding(string userConnerctionId, string data) | |
| { | |
| if (string.IsNullOrEmpty(userConnerctionId)) | |
| { | |
| return; | |
| } | |
| //获得要发送的链接id列表 | |
| var sendEntitys = GetRrelatedSendList(userConnerctionId); | |
| if (sendEntitys != null) | |
| { | |
| foreach (var model in sendEntitys) | |
| { | |
| if (model != null) | |
| { | |
| //指定用户发送消息 | |
| await Connection.Send(model.UserConnerctionId, data); | |
| LogHelper.DebugAsync($"服务器转发消息给用户:{model.UserId}|{model.UserType},内容为:{data}"); | |
| } | |
| } | |
| } | |
| //记录用户记录 | |
| DeviceOnlineModel entity = UserModelList.FirstOrDefaultV(o => o.UserConnerctionId == userConnerctionId); | |
| if (entity != null) | |
| { | |
| //指令发送成功后回复发送端发送成功 | |
| if (entity.UserType == (int) UserType.SysWebUser) | |
| { | |
| var dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(data); | |
| if (dic["text"].Equals("restart") | |
| || dic["text"].Equals("shutdown") | |
| || dic["text"].Equals("resumedefault")) | |
| { | |
| await Connection.Send(entity.UserConnerctionId, "MainSendOK"); | |
| } | |
| } | |
| LogHelper.DebugAsync("服务器接收到【" + (entity.UserType == (int) UserType.SysWebUser ? "WEB" : "设备") + | |
| "】用户【" + entity.UserId + "】,消息内容为:" + data); | |
| } | |
| } | |
| /// <summary> | |
| /// 获得发送连接id列表 | |
| /// </summary> | |
| /// <param name="userConnerctionId"></param> | |
| /// <returns></returns> | |
| public List<DeviceOnlineModel> GetRrelatedSendList(string userConnerctionId) | |
| { | |
| //发送消息的用户 | |
| var entity = UserModelList.FirstOrDefaultV(q => q.UserConnerctionId == userConnerctionId); | |
| if (entity != null) | |
| { | |
| var usertype = entity.UserType == (int) UserType.AppUser | |
| ? (int) UserType.SysWebUser | |
| : (int) UserType.AppUser; | |
| //要推送消息的用户 | |
| var sendEntitys = UserModelList.WhereV(q => q.UserId == entity.UserId && q.UserType == usertype) | |
| .ToList(); | |
| return sendEntitys; | |
| } | |
| return null; | |
| } | |
| /// <summary> | |
| /// 服务器强制断开连接 | |
| /// </summary> | |
| /// <param name="connectionId"></param> | |
| /// <param name="isSendErrMsg"></param> | |
| private async Task ServiceDisconnect(string connectionId, bool isSendErrMsg = true) | |
| { | |
| await GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections() | |
| .First(o => o.ConnectionId == connectionId).Disconnect(); | |
| if (isSendErrMsg) | |
| { | |
| //错误指令返回 | |
| Connection.SendErrMsg(connectionId, "非法连接,强制断开"); | |
| } | |
| } | |
| } | |
| } |
原文:https://www.cnblogs.com/zengtianli/p/12746504.html