mh_frame_sps/APT.Infrastructure.Api/Helper/WebSocketServiceHelper.cs

302 lines
11 KiB
C#
Raw Permalink Normal View History

2026-04-07 13:47:52 +08:00
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
{
/// <summary>
/// webSocket 服务帮助类
/// </summary>
public static class WebSocketServiceHelper
{
private static List<WebSocketClientInfo> _clientInfos;
public static List<WebSocketClientInfo> ClintInfos
{
get
{
if (_clientInfos == null)
_clientInfos = new List<WebSocketClientInfo>();
return _clientInfos;
}
}
public static List<Guid> UserIds
{
get
{
return ClintInfos.Where(t => t.UserId != null).Select(t => t.UserId.Value).ToList();
}
}
/// <summary>
/// 初始化WebSocket服务
/// </summary>
/// <param name="port"></param>
/// <param name="onOpen"></param>
/// <param name="onClose"></param>
/// <param name="onMessage"></param>
public static void InitService(int port,
Func<WebSocketClientInfo, WebSocketResponseInfo>
onOpen,
Func<WebSocketClientInfo, WebSocketRequestInfo, WebSocketResponseInfo>
onMessage,
Action<Guid, WebSocketClientInfo>
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<WebSocketRequestInfo>(message);
if (requestInfo != null)
{
if (string.Compare(requestInfo.TypeCode, "P0001", true) == 0)//登入
{
if (!string.IsNullOrEmpty(requestInfo.Data))
{
var loginInfo = JsonConvert.DeserializeObject<WebSocketRequestLoginInfo>(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);
}
}
};
});
}
/// <summary>
/// 发生消息到所有用户
/// </summary>
/// <param name="responseInfo"></param>
public static void SendToAll(WebSocketResponseInfo responseInfo)
{
SendToAll(responseInfo, null);
}
/// <summary>
/// 发生消息到所有用户
/// </summary>
/// <param name="responseInfo"></param>
/// <param name="checkClientInfoFunc">检查客户端有效性</param>
public static void SendToAll(WebSocketResponseInfo responseInfo, Func<WebSocketClientInfo, bool> checkClientInfoFunc = null)
{
if (responseInfo == null) return;
List<WebSocketResponseInfo> webSocketResponseInfos = new List<WebSocketResponseInfo>();
webSocketResponseInfos.Add(responseInfo);
SendToAll(webSocketResponseInfos, checkClientInfoFunc);
}
/// <summary>
/// 发送信息到所有用户
/// </summary>
/// <param name="responseInfos"></param>
public static void SendToAll(List<WebSocketResponseInfo> responseInfos)
{
SendToAll(responseInfos, null);
}
/// <summary>
/// 发送信息到所有用户
/// </summary>
/// <param name="responseInfos"></param>
/// <param name="checkClientInfoFunc">检查客户端有效性</param>
public static void SendToAll(List<WebSocketResponseInfo> responseInfos, Func<WebSocketClientInfo, bool> 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));
});
}
});
}
/// <summary>
/// 发送消息到指定用户
/// </summary>
/// <param name="userId"></param>
/// <param name="responseInfo"></param>
public static void SendToUser(Guid userId, WebSocketResponseInfo responseInfo)
{
if (responseInfo == null) return;
List<WebSocketResponseUserInfo> responseUseInfos = new List<WebSocketResponseUserInfo>();
WebSocketResponseUserInfo info = new WebSocketResponseUserInfo();
info.UserId = userId;
info.Data = responseInfo.Data;
info.TypeCode = responseInfo.TypeCode;
responseUseInfos.Add(info);
SendToUser(responseUseInfos);
}
/// <summary>
/// 发送消息到指定用户
/// </summary>
/// <param name="responseUseInfos"></param>
public static void SendToUser(List<WebSocketResponseUserInfo> 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; }
}
}