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, "非法連接,強制斷開"); | |
} | |
} | |
} | |
} |