using APT.Infrastructure.Api.Redis; using APT.Infrastructure.Core; using Fleck; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; namespace APT.Infrastructure.Api { /// /// webSocket 服务帮助类 /// public static class WebSocketServiceHelper { private static List _clientInfos; public static List ClintInfos { get { if (_clientInfos == null) _clientInfos = new List(); return _clientInfos; } } public static List UserIds { get { return ClintInfos.Where(t => t.UserId != null).Select(t => t.UserId.Value).ToList(); } } /// /// 初始化WebSocket服务 /// /// /// /// /// public static void InitService(int port, Func onOpen, Func onMessage, Action onClose) { FleckLog.Level = LogLevel.Debug; var server = new WebSocketServer("ws://0.0.0.0:" + (port == 0 ? 8181 : port)); server.Start(socket => { socket.OnOpen = () => { WebSocketClientInfo webSocketClientInfo = new WebSocketClientInfo(); webSocketClientInfo.WebSocketConnection = socket; ClintInfos.Add(webSocketClientInfo); if (onOpen != null) { var ret = onOpen(webSocketClientInfo); if (ret != null) socket.Send(JsonConvert.SerializeObject(ret)); } }; socket.OnClose = () => { var info = ClintInfos.FirstOrDefault(t => t.WebSocketConnection == socket); if (info != null) ClintInfos.Remove(info); if (onClose != null && info?.UserId != null) onClose(info.UserId.Value, info); }; socket.OnMessage = message => { var info = ClintInfos.FirstOrDefault(t => t.WebSocketConnection == socket); if (info != null) { try { var requestInfo = JsonConvert.DeserializeObject(message); if (requestInfo != null) { if (string.Compare(requestInfo.TypeCode, "P0001", true) == 0)//登入 { if (!string.IsNullOrEmpty(requestInfo.Data)) { var loginInfo = JsonConvert.DeserializeObject(requestInfo.Data); if (loginInfo != null) { info.Tenant = loginInfo.Tenant; info.UserId = loginInfo.UserId; info.DbConn = GetDbConn(info.Tenant); info.UserName = loginInfo.UserName; info.ClientType = (WebSocketClientTypeEnum)loginInfo.ClientType; } } } if (onMessage != null) { var ret = onMessage(info, requestInfo); if (ret != null) socket.Send(JsonConvert.SerializeObject(ret)); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } }; }); } /// /// 发生消息到所有用户 /// /// public static void SendToAll(WebSocketResponseInfo responseInfo) { SendToAll(responseInfo, null); } /// /// 发生消息到所有用户 /// /// /// 检查客户端有效性 public static void SendToAll(WebSocketResponseInfo responseInfo, Func checkClientInfoFunc = null) { if (responseInfo == null) return; List webSocketResponseInfos = new List(); webSocketResponseInfos.Add(responseInfo); SendToAll(webSocketResponseInfos, checkClientInfoFunc); } /// /// 发送信息到所有用户 /// /// public static void SendToAll(List responseInfos) { SendToAll(responseInfos, null); } /// /// 发送信息到所有用户 /// /// /// 检查客户端有效性 public static void SendToAll(List responseInfos, Func checkClientInfoFunc = null) { if (responseInfos == null || !responseInfos.Any() || !ClintInfos.Any()) return; ClintInfos.ForEach(t => { if (checkClientInfoFunc != null) { if (!checkClientInfoFunc(t)) return; } if (t.WebSocketConnection != null) { responseInfos.ForEach(t1 => { t.WebSocketConnection.Send(JsonConvert.SerializeObject(t1)); }); } }); } /// /// 发送消息到指定用户 /// /// /// public static void SendToUser(Guid userId, WebSocketResponseInfo responseInfo) { if (responseInfo == null) return; List responseUseInfos = new List(); WebSocketResponseUserInfo info = new WebSocketResponseUserInfo(); info.UserId = userId; info.Data = responseInfo.Data; info.TypeCode = responseInfo.TypeCode; responseUseInfos.Add(info); SendToUser(responseUseInfos); } /// /// 发送消息到指定用户 /// /// public static void SendToUser(List responseUseInfos) { if (responseUseInfos == null || !responseUseInfos.Any()) return; responseUseInfos.ForEach(t => { if (t.UserId != null) { var userClientInfo = ClintInfos?.Where(t1 => t1.UserId == t.UserId && t1.WebSocketConnection != null).ToList(); userClientInfo.ForEach(t1 => { t1.WebSocketConnection.Send(JsonConvert.SerializeObject(t)); }); } }); } public static string GetDbConn(string tenantName) { //redis取數據 var deskey = ConfigurationManager.AppSettings["ConnDataKey"]; if (string.IsNullOrEmpty(deskey)) deskey = "optenergy2021001"; var tenantKey = ConfigurationManager.AppSettings["TenantConnKey"] + tenantName; if (CsRedisManager.KeyExists(tenantKey)) { var conns = CsRedisManager.StringGet(tenantKey); var retConn = conns == "null" ? null : EncryptHelper.AesDecrypt(conns, deskey); ; return retConn; } else { var url = ConfigurationManager.AppSettings["ConnApiUrl"]; if (!string.IsNullOrEmpty(url)) { var deData = WebUtils.Get(url, "code", tenantName, ""); //LoggerManager.GetLogger().Info($"TenantData:{deData}"); return EncryptHelper.AesDecrypt(deData, deskey); } } return ConfigurationManager.ConnectionStrings["default"]; } } public enum WebSocketClientTypeEnum { WEB后台 = 0, 客户端 = 1, APP = 2, 默认 = 99, } public class WebSocketClientInfo { public IWebSocketConnection WebSocketConnection { get; set; } public Guid? UserId { get; set; } public string UserName { get; set; } public string Tenant { get; set; } public string DbConn { get; set; } public Guid? OrgId { get; set; } public WebSocketClientTypeEnum ClientType { get; set; } } public class WebSocketRequestInfo { public WebSocketRequestInfo() { this.TypeCode = "U0000"; } public string TypeCode { get; set; } public string Tenant { get; set; } public string Data { get; set; } } public class WebSocketResponseInfo { public WebSocketResponseInfo() { this.TypeCode = "U0000"; } public string TypeCode { get; set; } public object Data { get; set; } } public class WebSocketResponseUserInfo : WebSocketResponseInfo { public Guid? UserId { get; set; } } public class WebSocketRequestLoginInfo { public Guid? UserId { get; set; } public string UserName { get; set; } public string Tenant { get; set; } public string DbConn { get; set; } public Guid? OrgId { get; set; } public int ClientType { get; set; } } }