302 lines
11 KiB
C#
302 lines
11 KiB
C#
|
|
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; }
|
|||
|
|
}
|
|||
|
|
}
|