mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-03 00:00:49 +08:00
修改了WebSocket工具的抽象结构
This commit is contained in:
@@ -62,7 +62,7 @@ namespace Serein.FlowStartTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsRuning = true;
|
IsRuning = true;
|
||||||
_ = StartFlow(flowProjectData, fileDataPath);
|
_ = Task.Run(async () => await StartFlow(flowProjectData, fileDataPath));
|
||||||
while (IsRuning)
|
while (IsRuning)
|
||||||
{
|
{
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ namespace Serein.Library
|
|||||||
else if (_emitMethodType == EmitMethodType.Task && _emitDelegate is Func<object, object[], Task> task)
|
else if (_emitMethodType == EmitMethodType.Task && _emitDelegate is Func<object, object[], Task> task)
|
||||||
{
|
{
|
||||||
await task.Invoke(instance, args);
|
await task.Invoke(instance, args);
|
||||||
result = null;
|
|
||||||
}
|
}
|
||||||
else if (_emitMethodType == EmitMethodType.Func && _emitDelegate is Func<object, object[], object> func)
|
else if (_emitMethodType == EmitMethodType.Func && _emitDelegate is Func<object, object[], object> func)
|
||||||
{
|
{
|
||||||
|
|||||||
180
Library/Network/Http/ApiHandleConfig.cs
Normal file
180
Library/Network/Http/ApiHandleConfig.cs
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Serein.Library.Web;
|
||||||
|
|
||||||
|
namespace Serein.Library.Network
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// api请求处理模块
|
||||||
|
/// </summary>
|
||||||
|
public class ApiHandleConfig
|
||||||
|
{
|
||||||
|
private readonly DelegateDetails delegateDetails;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Post请求处理方法中,入参参数类型
|
||||||
|
/// </summary>
|
||||||
|
public enum PostArgType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 不做处理
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
/// <summary>
|
||||||
|
/// 使用Url参数
|
||||||
|
/// </summary>
|
||||||
|
IsUrlData,
|
||||||
|
/// <summary>
|
||||||
|
/// 使用整体的Boby参数
|
||||||
|
/// </summary>
|
||||||
|
IsBobyData,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加处理配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="methodInfo"></param>
|
||||||
|
public ApiHandleConfig(MethodInfo methodInfo)
|
||||||
|
{
|
||||||
|
delegateDetails = new DelegateDetails(methodInfo);
|
||||||
|
var parameterInfos = methodInfo.GetParameters();
|
||||||
|
ParameterType = parameterInfos.Select(t => t.ParameterType).ToArray();
|
||||||
|
ParameterName = parameterInfos.Select(t => t.Name.ToLower()).ToArray();
|
||||||
|
|
||||||
|
PostArgTypes = parameterInfos.Select(p =>
|
||||||
|
{
|
||||||
|
bool isUrlData = p.GetCustomAttribute(typeof(UrlAttribute)) != null;
|
||||||
|
bool isBobyData = p.GetCustomAttribute(typeof(BobyAttribute)) != null;
|
||||||
|
if (isBobyData)
|
||||||
|
{
|
||||||
|
return PostArgType.IsBobyData;
|
||||||
|
}
|
||||||
|
else if (isUrlData)
|
||||||
|
{
|
||||||
|
return PostArgType.IsUrlData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PostArgType.None;
|
||||||
|
}
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly PostArgType[] PostArgTypes;
|
||||||
|
private readonly string[] ParameterName;
|
||||||
|
private readonly Type[] ParameterType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理Get请求
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public object[] GetArgsOfGet(Dictionary<string, string> routeData)
|
||||||
|
{
|
||||||
|
object[] args = new object[ParameterType.Length];
|
||||||
|
for (int i = 0; i < ParameterType.Length; i++)
|
||||||
|
{
|
||||||
|
var type = ParameterType[i];
|
||||||
|
var argName = ParameterName[i];
|
||||||
|
if (routeData.TryGetValue(argName, out var argValue))
|
||||||
|
{
|
||||||
|
if (type == typeof(string))
|
||||||
|
{
|
||||||
|
args[i] = argValue;
|
||||||
|
}
|
||||||
|
else // if (type.IsValueType)
|
||||||
|
{
|
||||||
|
args[i] = JsonConvert.DeserializeObject(argValue, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args[i] = type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetArgsOfPost(Dictionary<string, string> routeData, JObject jsonObject)
|
||||||
|
{
|
||||||
|
object[] args = new object[ParameterType.Length];
|
||||||
|
for (int i = 0; i < ParameterType.Length; i++)
|
||||||
|
{
|
||||||
|
var type = ParameterType[i];
|
||||||
|
var argName = ParameterName[i];
|
||||||
|
if (PostArgTypes[i] == PostArgType.IsUrlData)
|
||||||
|
{
|
||||||
|
if (routeData.TryGetValue(argName, out var argValue))
|
||||||
|
{
|
||||||
|
if (type == typeof(string))
|
||||||
|
{
|
||||||
|
args[i] = argValue;
|
||||||
|
}
|
||||||
|
else // if (type.IsValueType)
|
||||||
|
{
|
||||||
|
args[i] = JsonConvert.DeserializeObject(argValue, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args[i] = type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (jsonObject != null && PostArgTypes[i] == PostArgType.IsBobyData)
|
||||||
|
{
|
||||||
|
args[i] = jsonObject;
|
||||||
|
}
|
||||||
|
else if (jsonObject != null)
|
||||||
|
{
|
||||||
|
var jsonValue = jsonObject.GetValue(argName);
|
||||||
|
if (jsonValue is null)
|
||||||
|
{
|
||||||
|
// 值类型返回默认值,引用类型返回null
|
||||||
|
args[i] = type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args[i] = jsonValue.ToObject(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<object> HandleAsync(object instance, object[] args)
|
||||||
|
{
|
||||||
|
object result = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = await delegateDetails.InvokeAsync(instance, args);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
await Console.Out.WriteLineAsync(ex.Message);
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Serein.Library.Api;
|
using Serein.Library.Api;
|
||||||
|
using Serein.Library.Network;
|
||||||
using Serein.Library.Utils;
|
using Serein.Library.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
@@ -36,177 +37,6 @@ namespace Serein.Library.Web
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// api请求处理模块
|
|
||||||
/// </summary>
|
|
||||||
public class ApiHandleConfig
|
|
||||||
{
|
|
||||||
private readonly DelegateDetails delegateDetails;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Post请求处理方法中,入参参数类型
|
|
||||||
/// </summary>
|
|
||||||
public enum PostArgType
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 不做处理
|
|
||||||
/// </summary>
|
|
||||||
None,
|
|
||||||
/// <summary>
|
|
||||||
/// 使用Url参数
|
|
||||||
/// </summary>
|
|
||||||
IsUrlData,
|
|
||||||
/// <summary>
|
|
||||||
/// 使用整体的Boby参数
|
|
||||||
/// </summary>
|
|
||||||
IsBobyData,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 添加处理配置
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="methodInfo"></param>
|
|
||||||
public ApiHandleConfig(MethodInfo methodInfo)
|
|
||||||
{
|
|
||||||
delegateDetails = new DelegateDetails(methodInfo);
|
|
||||||
var parameterInfos = methodInfo.GetParameters();
|
|
||||||
ParameterType = parameterInfos.Select(t => t.ParameterType).ToArray();
|
|
||||||
ParameterName = parameterInfos.Select(t => t.Name.ToLower()).ToArray();
|
|
||||||
|
|
||||||
PostArgTypes = parameterInfos.Select(p =>
|
|
||||||
{
|
|
||||||
bool isUrlData = p.GetCustomAttribute(typeof(UrlAttribute)) != null;
|
|
||||||
bool isBobyData = p.GetCustomAttribute(typeof(BobyAttribute)) != null;
|
|
||||||
if (isBobyData)
|
|
||||||
{
|
|
||||||
return PostArgType.IsBobyData;
|
|
||||||
}
|
|
||||||
else if (isUrlData)
|
|
||||||
{
|
|
||||||
return PostArgType.IsUrlData;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return PostArgType.None;
|
|
||||||
}
|
|
||||||
}).ToArray();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
private readonly PostArgType[] PostArgTypes;
|
|
||||||
private readonly string[] ParameterName;
|
|
||||||
private readonly Type[] ParameterType;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 处理Get请求
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="instance"></param>
|
|
||||||
/// <param name="routeData"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<object> HandleGet(object instance, Dictionary<string, string> routeData)
|
|
||||||
{
|
|
||||||
object[] args = new object[ParameterType.Length];
|
|
||||||
for (int i = 0; i < ParameterType.Length; i++)
|
|
||||||
{
|
|
||||||
var type = ParameterType[i];
|
|
||||||
var argName = ParameterName[i];
|
|
||||||
if (routeData.TryGetValue(argName, out var argValue))
|
|
||||||
{
|
|
||||||
if (type == typeof(string))
|
|
||||||
{
|
|
||||||
args[i] = argValue;
|
|
||||||
}
|
|
||||||
else // if (type.IsValueType)
|
|
||||||
{
|
|
||||||
args[i] = JsonConvert.DeserializeObject(argValue, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
args[i] = type.IsValueType ? Activator.CreateInstance(type) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
object result = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = await delegateDetails.InvokeAsync(instance, args);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
await Console.Out.WriteLineAsync(ex.Message);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<object> HandlePost(object instance, JObject jsonObject, Dictionary<string, string> routeData)
|
|
||||||
{
|
|
||||||
object[] args = new object[ParameterType.Length];
|
|
||||||
for (int i = 0; i < ParameterType.Length; i++)
|
|
||||||
{
|
|
||||||
var type = ParameterType[i];
|
|
||||||
var argName = ParameterName[i];
|
|
||||||
if (PostArgTypes[i] == PostArgType.IsUrlData)
|
|
||||||
{
|
|
||||||
if (routeData.TryGetValue(argName, out var argValue))
|
|
||||||
{
|
|
||||||
if (type == typeof(string))
|
|
||||||
{
|
|
||||||
args[i] = argValue;
|
|
||||||
}
|
|
||||||
else // if (type.IsValueType)
|
|
||||||
{
|
|
||||||
args[i] = JsonConvert.DeserializeObject(argValue, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
args[i] = type.IsValueType ? Activator.CreateInstance(type) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (PostArgTypes[i] == PostArgType.IsBobyData)
|
|
||||||
{
|
|
||||||
args[i] = jsonObject;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var jsonValue = jsonObject.GetValue(argName);
|
|
||||||
if (jsonValue is null)
|
|
||||||
{
|
|
||||||
// 值类型返回默认值,引用类型返回null
|
|
||||||
args[i] = type.IsValueType ? Activator.CreateInstance(type) : null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
args[i] = jsonValue.ToObject(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object result = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = await delegateDetails.InvokeAsync(instance, args);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
await Console.Out.WriteLineAsync(ex.Message);
|
|
||||||
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -232,8 +62,6 @@ namespace Serein.Library.Web
|
|||||||
|
|
||||||
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, ApiHandleConfig>> HandleModels = new ConcurrentDictionary<string, ConcurrentDictionary<string, ApiHandleConfig>>();
|
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, ApiHandleConfig>> HandleModels = new ConcurrentDictionary<string, ConcurrentDictionary<string, ApiHandleConfig>>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Router(ISereinIOC SereinIOC)
|
public Router(ISereinIOC SereinIOC)
|
||||||
{
|
{
|
||||||
this.SereinIOC = SereinIOC;
|
this.SereinIOC = SereinIOC;
|
||||||
@@ -302,21 +130,19 @@ namespace Serein.Library.Web
|
|||||||
public async Task<bool> ProcessingAsync(HttpListenerContext context)
|
public async Task<bool> ProcessingAsync(HttpListenerContext context)
|
||||||
{
|
{
|
||||||
var request = context.Request; // 获取请求对象
|
var request = context.Request; // 获取请求对象
|
||||||
var response = context.Response; // 获取响应对象
|
var template = request.Url.AbsolutePath.ToLower();
|
||||||
var url = request.Url; // 获取请求的 URL
|
|
||||||
var httpMethod = request.HttpMethod; // 获取请求的 HTTP 方法
|
|
||||||
var template = request.Url.AbsolutePath.ToLower();
|
|
||||||
if (!_controllerTypes.TryGetValue(template, out Type controllerType))
|
if (!_controllerTypes.TryGetValue(template, out Type controllerType))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // 没有对应的方法
|
||||||
}
|
}
|
||||||
|
var httpMethod = request.HttpMethod; // 获取请求的 HTTP 方法
|
||||||
if (!HandleModels.TryGetValue(httpMethod, out var modules))
|
if (!HandleModels.TryGetValue(httpMethod, out var modules))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // 没有对应的处理模块
|
||||||
}
|
}
|
||||||
if (!modules.TryGetValue(template, out var config))
|
if (!modules.TryGetValue(template, out var config))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // 没有对应的处理配置
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase controllerInstance = (ControllerBase)SereinIOC.Instantiate(controllerType);
|
ControllerBase controllerInstance = (ControllerBase)SereinIOC.Instantiate(controllerType);
|
||||||
@@ -326,25 +152,30 @@ namespace Serein.Library.Web
|
|||||||
return false; // 未找到控制器实例
|
return false; // 未找到控制器实例
|
||||||
}
|
}
|
||||||
|
|
||||||
object invokeResult;
|
|
||||||
|
var url = request.Url; // 获取请求的完整URL
|
||||||
var routeValues = GetUrlData(url); // 解析 URL 获取路由参数
|
var routeValues = GetUrlData(url); // 解析 URL 获取路由参数
|
||||||
controllerInstance.Url = url.AbsolutePath;
|
controllerInstance.Url = url.AbsolutePath;
|
||||||
|
|
||||||
|
object[] args;
|
||||||
switch (httpMethod)
|
switch (httpMethod)
|
||||||
{
|
{
|
||||||
case "GET":
|
case "GET":
|
||||||
invokeResult = await config.HandleGet(controllerInstance, routeValues);
|
args = config.GetArgsOfGet(routeValues); // Get请求
|
||||||
break;
|
break;
|
||||||
case "POST":
|
case "POST":
|
||||||
var requestBody = await ReadRequestBodyAsync(request); // 读取请求体内容
|
var requestBody = await ReadRequestBodyAsync(request); // 读取请求体内容
|
||||||
controllerInstance.BobyData = requestBody;
|
controllerInstance.BobyData = requestBody;
|
||||||
var requestJObject = JObject.Parse(requestBody);
|
var requestJObject = JObject.Parse(requestBody);
|
||||||
invokeResult = await config.HandlePost(controllerInstance, requestJObject, routeValues);
|
args = config.GetArgsOfPost(routeValues, requestJObject); // Post请求
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
invokeResult = null;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Return(response, invokeResult); // 返回结果
|
var invokeResult = await config.HandleAsync(controllerInstance, args);
|
||||||
|
|
||||||
|
var response = context.Response; // 获取响应对象
|
||||||
|
ResponseApiMsg(response, invokeResult); // 返回结果
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -371,7 +202,7 @@ namespace Serein.Library.Web
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
/// <param name="msg"></param>
|
/// <param name="msg"></param>
|
||||||
private static void Return(HttpListenerResponse response, object msg)
|
private static void ResponseApiMsg(HttpListenerResponse response, object msg)
|
||||||
{
|
{
|
||||||
string resultData;
|
string resultData;
|
||||||
if (response != null)
|
if (response != null)
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ namespace Serein.Library.Web
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 判断访问接口的频次是否正常
|
/// 判断访问接口的频次是否正常
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -86,10 +86,71 @@ namespace Serein.Library.Network.WebSocketCommunication
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class SocketHandleModule
|
|
||||||
|
internal class WebSocketHandleConfiguration : HandleConfiguration
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主题
|
||||||
|
/// </summary>
|
||||||
public string ThemeValue { get; set; } = string.Empty;
|
public string ThemeValue { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// socket模块处理数据配置
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
public class HandleConfiguration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Emit委托
|
||||||
|
/// </summary>
|
||||||
|
public DelegateDetails DelegateDetails { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 未捕获的异常跟踪
|
||||||
|
/// </summary>
|
||||||
|
public Action<Exception, Action<object>> OnExceptionTracking { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所使用的实例
|
||||||
|
/// </summary>
|
||||||
|
public ISocketHandleModule Instance { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否需要返回
|
||||||
|
/// </summary>
|
||||||
public bool IsReturnValue { get; set; } = true;
|
public bool IsReturnValue { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否要求必须不为null
|
||||||
|
/// </summary>
|
||||||
|
public bool ArgNotNull { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否使Data整体内容作为入参参数
|
||||||
|
/// </summary>
|
||||||
|
public bool[] UseData { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否使用消息ID作为入参参数
|
||||||
|
/// </summary>
|
||||||
|
public bool[] UseMsgId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数名称
|
||||||
|
/// </summary>
|
||||||
|
public string[] ParameterName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数类型
|
||||||
|
/// </summary>
|
||||||
|
public Type[] ParameterType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否检查变量为空
|
||||||
|
/// </summary>
|
||||||
|
public bool[] IsCheckArgNotNull { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -64,4 +65,6 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,250 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Serein.Library.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Reflection.Emit;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class JsonMsgHandleConfig
|
|
||||||
{
|
|
||||||
public Guid HandleGuid { get; }
|
|
||||||
|
|
||||||
|
|
||||||
internal JsonMsgHandleConfig(SocketHandleModule model,
|
|
||||||
ISocketHandleModule instance,
|
|
||||||
MethodInfo methodInfo,
|
|
||||||
Action<Exception, Action<object>> onExceptionTracking,
|
|
||||||
bool ArgNotNull)
|
|
||||||
{
|
|
||||||
DelegateDetails = new DelegateDetails(methodInfo);
|
|
||||||
this.Module = model;
|
|
||||||
Instance = instance;
|
|
||||||
var parameterInfos = methodInfo.GetParameters();
|
|
||||||
this.ParameterType = parameterInfos.Select(t => t.ParameterType).ToArray();
|
|
||||||
this.ParameterName = parameterInfos.Select(t => t.Name).ToArray();
|
|
||||||
this.HandleGuid = instance.HandleGuid;
|
|
||||||
this.OnExceptionTracking = onExceptionTracking;
|
|
||||||
this.ArgNotNull = ArgNotNull;
|
|
||||||
|
|
||||||
this.useData = parameterInfos.Select(p => p.GetCustomAttribute<UseDataAttribute>() != null).ToArray();
|
|
||||||
this.useMsgId = parameterInfos.Select(p => p.GetCustomAttribute<UseMsgIdAttribute>() != null).ToArray();
|
|
||||||
#if NET5_0_OR_GREATER
|
|
||||||
this.IsCheckArgNotNull = parameterInfos.Select(p => p.GetCustomAttribute<NotNullAttribute>() != null).ToArray();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(IsCheckArgNotNull is null)
|
|
||||||
{
|
|
||||||
IsCheckArgNotNull = parameterInfos.Select(p => p.GetCustomAttribute<NeedfulAttribute>() != null).ToArray();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 兼容两种非空特性的写法
|
|
||||||
var argNotNull = parameterInfos.Select(p => p.GetCustomAttribute<NeedfulAttribute>() != null).ToArray();
|
|
||||||
for (int i = 0; i < IsCheckArgNotNull.Length; i++)
|
|
||||||
{
|
|
||||||
if (!IsCheckArgNotNull[i] && argNotNull[i])
|
|
||||||
{
|
|
||||||
IsCheckArgNotNull[i] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 参数不能为空
|
|
||||||
/// </summary>
|
|
||||||
private bool ArgNotNull;
|
|
||||||
/// <summary>
|
|
||||||
/// Emit委托
|
|
||||||
/// </summary>
|
|
||||||
private readonly DelegateDetails DelegateDetails;
|
|
||||||
/// <summary>
|
|
||||||
/// 未捕获的异常跟踪
|
|
||||||
/// </summary>
|
|
||||||
private readonly Action<Exception, Action<object>> OnExceptionTracking;
|
|
||||||
/// <summary>
|
|
||||||
/// 所在的模块
|
|
||||||
/// </summary>
|
|
||||||
private readonly SocketHandleModule Module;
|
|
||||||
/// <summary>
|
|
||||||
/// 所使用的实例
|
|
||||||
/// </summary>
|
|
||||||
private readonly ISocketHandleModule Instance;
|
|
||||||
/// <summary>
|
|
||||||
/// 参数名称
|
|
||||||
/// </summary>
|
|
||||||
private readonly string[] ParameterName;
|
|
||||||
/// <summary>
|
|
||||||
/// 参数类型
|
|
||||||
/// </summary>
|
|
||||||
private readonly Type[] ParameterType;
|
|
||||||
/// <summary>
|
|
||||||
/// 是否使Data整体内容作为入参参数
|
|
||||||
/// </summary>
|
|
||||||
private readonly bool[] useData;
|
|
||||||
/// <summary>
|
|
||||||
/// 是否使用消息ID作为入参参数
|
|
||||||
/// </summary>
|
|
||||||
private readonly bool[] useMsgId;
|
|
||||||
/// <summary>
|
|
||||||
/// 是否检查变量为空
|
|
||||||
/// </summary>
|
|
||||||
private readonly bool[] IsCheckArgNotNull;
|
|
||||||
|
|
||||||
public async void Handle(Func<object, Task> SendAsync,string msgId, JObject jsonObject)
|
|
||||||
{
|
|
||||||
object[] args = new object[ParameterType.Length];
|
|
||||||
bool isCanInvoke = true;; // 表示是否可以调用方法
|
|
||||||
for (int i = 0; i < ParameterType.Length; i++)
|
|
||||||
{
|
|
||||||
var type = ParameterType[i]; // 入参变量类型
|
|
||||||
var argName = ParameterName[i]; // 入参参数名称
|
|
||||||
#region 传递消息ID
|
|
||||||
if (useMsgId[i])
|
|
||||||
{
|
|
||||||
args[i] = msgId;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region DATA JSON数据
|
|
||||||
else if (useData[i])
|
|
||||||
{
|
|
||||||
args[i] = jsonObject.ToObject(type);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region 值类型参数
|
|
||||||
else if (type.IsValueType)
|
|
||||||
{
|
|
||||||
var jsonValue = jsonObject.GetValue(argName);
|
|
||||||
if (!(jsonValue is null))
|
|
||||||
{
|
|
||||||
args[i] = jsonValue.ToObject(type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ArgNotNull && !IsCheckArgNotNull[i]) // 检查不能为空
|
|
||||||
{
|
|
||||||
|
|
||||||
args[i] = Activator.CreateInstance(type); // 值类型返回默认值
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isCanInvoke = false; // 参数不能为空,终止调用
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region 引用类型参数
|
|
||||||
else if (type.IsClass)
|
|
||||||
{
|
|
||||||
var jsonValue = jsonObject.GetValue(argName);
|
|
||||||
if (!(jsonValue is null))
|
|
||||||
{
|
|
||||||
args[i] = jsonValue.ToObject(type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ArgNotNull && !IsCheckArgNotNull[i])
|
|
||||||
{
|
|
||||||
|
|
||||||
args[i] = null; // 引用类型返回null
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isCanInvoke = false; // 参数不能为空,终止调用
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region 传递消息委托
|
|
||||||
else if (type.IsGenericType) // 传递SendAsync委托
|
|
||||||
{
|
|
||||||
if (type.IsAssignableFrom(typeof(Func<object, Task>)))
|
|
||||||
{
|
|
||||||
args[i] = new Func<object, Task>(async data =>
|
|
||||||
{
|
|
||||||
var jsonText = JsonConvert.SerializeObject(data);
|
|
||||||
await SendAsync.Invoke(jsonText);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (type.IsAssignableFrom(typeof(Func<string, Task>)))
|
|
||||||
{
|
|
||||||
args[i] = new Func<string, Task>(async data =>
|
|
||||||
{
|
|
||||||
await SendAsync.Invoke(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (type.IsAssignableFrom(typeof(Action<object>)))
|
|
||||||
{
|
|
||||||
args[i] = new Action<object>(async data =>
|
|
||||||
{
|
|
||||||
var jsonText = JsonConvert.SerializeObject(data);
|
|
||||||
await SendAsync.Invoke(jsonText);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (type.IsAssignableFrom(typeof(Action<string>)))
|
|
||||||
{
|
|
||||||
args[i] = new Action<string>(async data =>
|
|
||||||
{
|
|
||||||
var jsonText = JsonConvert.SerializeObject(data);
|
|
||||||
await SendAsync.Invoke(jsonText);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isCanInvoke)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
object result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = await DelegateDetails.InvokeAsync(Instance, args);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
result = null;
|
|
||||||
await Console.Out.WriteLineAsync(ex.Message);
|
|
||||||
this.OnExceptionTracking.Invoke(ex, (async exData =>
|
|
||||||
{
|
|
||||||
await SendAsync.Invoke(exData);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Module.IsReturnValue)
|
|
||||||
{
|
|
||||||
_ = SendAsync.Invoke(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Json消息处理模块
|
/// Json消息处理模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -19,43 +20,35 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Json消息处理模块
|
/// Json消息处理模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WebSocketHandleModule(string themeJsonKey, string dataJsonKey, string msgIdJsonKey)
|
public WebSocketHandleModule(WebSocketHandleModuleConfig config)
|
||||||
{
|
{
|
||||||
this.ThemeJsonKey = themeJsonKey;
|
this.moduleConfig = config;
|
||||||
this.DataJsonKey = dataJsonKey;
|
|
||||||
this.MsgIdJsonKey = msgIdJsonKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 指示处理模块该使用 Json 中的哪个 Key 作为业务区别字段
|
/// 模块的处理配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ThemeJsonKey { get; }
|
private readonly WebSocketHandleModuleConfig moduleConfig;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 指示处理模块该使用 Json 中的哪个 Key 作为业务数据字段
|
/// 用来判断消息是否重复
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DataJsonKey { get; }
|
private HashSet<string> _myMsgIdHash = new HashSet<string>();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 指示处理模块该使用 Json 中的哪个 Key 作为业务消息ID字段
|
|
||||||
/// </summary>
|
|
||||||
public string MsgIdJsonKey { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 存储处理数据的配置
|
/// 存储处理数据的配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ConcurrentDictionary<string, JsonMsgHandleConfig> MyHandleConfigs = new ConcurrentDictionary<string, JsonMsgHandleConfig>();
|
public ConcurrentDictionary<string, HandleConfiguration> MyHandleConfigs = new ConcurrentDictionary<string, HandleConfiguration>();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加处理配置
|
/// 添加处理配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="module">处理模块</param>
|
/// <param name="config">处理模块</param>
|
||||||
/// <param name="jsonMsgHandleConfig">处理配置</param>
|
internal bool AddHandleConfigs(WebSocketHandleConfiguration config)
|
||||||
internal bool AddHandleConfigs(SocketHandleModule module,JsonMsgHandleConfig jsonMsgHandleConfig)
|
|
||||||
{
|
{
|
||||||
if (!MyHandleConfigs.ContainsKey(module.ThemeValue))
|
if (!MyHandleConfigs.ContainsKey(config.ThemeValue))
|
||||||
{
|
{
|
||||||
MyHandleConfigs[module.ThemeValue] = jsonMsgHandleConfig;
|
MyHandleConfigs[config.ThemeValue] = config;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -74,7 +67,7 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
foreach (var kv in MyHandleConfigs.ToArray())
|
foreach (var kv in MyHandleConfigs.ToArray())
|
||||||
{
|
{
|
||||||
var config = kv.Value;
|
var config = kv.Value;
|
||||||
if (config.HandleGuid.Equals(socketControlBase.HandleGuid))
|
if (config.Instance.HandleGuid.Equals(socketControlBase.HandleGuid))
|
||||||
{
|
{
|
||||||
MyHandleConfigs.TryRemove(kv.Key, out _);
|
MyHandleConfigs.TryRemove(kv.Key, out _);
|
||||||
}
|
}
|
||||||
@@ -91,38 +84,42 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
MyHandleConfigs.Clear();
|
MyHandleConfigs.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashSet<string> _myMsgIdHash = new HashSet<string>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 处理JSON数据
|
/// 处理JSON数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sendAsync"></param>
|
public async void HandleSocketMsg(WebSocketMsgContext context) // Func<string, Task> sendAsync, JObject jsonObject
|
||||||
/// <param name="jsonObject"></param>
|
|
||||||
public void HandleSocketMsg(Func<string, Task> sendAsync, JObject jsonObject)
|
|
||||||
{
|
{
|
||||||
// 获取到消息
|
|
||||||
string theme = jsonObject.GetValue(ThemeJsonKey)?.ToString();
|
var jsonObject = context.JsonObject; // 获取到消息
|
||||||
|
string theme = jsonObject.GetValue(moduleConfig.ThemeJsonKey)?.ToString();
|
||||||
if (!MyHandleConfigs.TryGetValue(theme, out var handldConfig))
|
if (!MyHandleConfigs.TryGetValue(theme, out var handldConfig))
|
||||||
{
|
{
|
||||||
// 没有主题
|
return; // 没有主题
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
string msgId = jsonObject.GetValue(MsgIdJsonKey)?.ToString();
|
context.MsgTheme = theme; // 添加主题
|
||||||
|
string msgId = jsonObject.GetValue(moduleConfig.MsgIdJsonKey)?.ToString();
|
||||||
if (_myMsgIdHash.Contains(msgId))
|
if (_myMsgIdHash.Contains(msgId))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"[{msgId}]{theme} 消息重复");
|
Console.WriteLine($"[{msgId}]{theme} 消息重复");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
context.MsgId = msgId; // 添加 ID
|
||||||
_myMsgIdHash.Add(msgId);
|
_myMsgIdHash.Add(msgId);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
JObject dataObj = jsonObject.GetValue(DataJsonKey)?.ToObject<JObject>();
|
var dataObj = jsonObject.GetValue(moduleConfig.DataJsonKey)?.ToObject<JObject>();
|
||||||
handldConfig.Handle(async (data) =>
|
context.MsgData = dataObj; // 添加消息
|
||||||
|
if (TryGetParameters(handldConfig, context, out var args))
|
||||||
{
|
{
|
||||||
await this.SendAsync(sendAsync, msgId, theme, data);
|
var result = await WebSocketHandleModule.HandleAsync(handldConfig, args);
|
||||||
}, msgId, dataObj);
|
if (handldConfig.IsReturnValue)
|
||||||
|
{
|
||||||
|
await context.RepliedAsync(moduleConfig, context, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -133,52 +130,130 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送消息
|
/// 调用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sendAsync"></param>
|
/// <param name="config"></param>
|
||||||
/// <param name="msgId"></param>
|
/// <param name="args"></param>
|
||||||
/// <param name="theme"></param>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task SendAsync(Func<string, Task> sendAsync,string msgId, string theme, object data)
|
public static async Task<object> HandleAsync(HandleConfiguration config, object[] args)
|
||||||
{
|
{
|
||||||
JObject jsonData;
|
var result = await config.DelegateDetails.InvokeAsync(config.Instance, args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (data is null)
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取入参参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">处理配置</param>
|
||||||
|
/// <param name="context">处理上下文</param>
|
||||||
|
/// <param name="args">返回的入参参数</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static bool TryGetParameters(HandleConfiguration config,WebSocketMsgContext context, out object[] args)
|
||||||
|
{
|
||||||
|
args = new object[config.ParameterType.Length];
|
||||||
|
bool isCanInvoke = true; ; // 表示是否可以调用方法
|
||||||
|
|
||||||
|
for (int i = 0; i < config.ParameterType.Length; i++)
|
||||||
{
|
{
|
||||||
jsonData = new JObject()
|
var type = config.ParameterType[i]; // 入参变量类型
|
||||||
|
var argName = config.ParameterName[i]; // 入参参数名称
|
||||||
|
#region 传递消息ID
|
||||||
|
if (config.UseMsgId[i])
|
||||||
{
|
{
|
||||||
[MsgIdJsonKey] = msgId,
|
args[i] = context.MsgId;
|
||||||
[ThemeJsonKey] = theme,
|
}
|
||||||
};
|
#endregion
|
||||||
}
|
#region DATA JSON数据
|
||||||
else
|
else if (config.UseData[i])
|
||||||
{
|
{
|
||||||
|
args[i] = context.MsgData.ToObject(type);
|
||||||
JToken dataToken;
|
}
|
||||||
if ((data is System.Collections.IEnumerable || data is Array))
|
#endregion
|
||||||
|
#region 值类型参数
|
||||||
|
else if (type.IsValueType)
|
||||||
|
{
|
||||||
|
var jsonValue = context.MsgData.GetValue(argName);
|
||||||
|
if (!(jsonValue is null))
|
||||||
{
|
{
|
||||||
dataToken = JArray.FromObject(data);
|
args[i] = jsonValue.ToObject(type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataToken = JObject.FromObject(data);
|
if (config.ArgNotNull && !config.IsCheckArgNotNull[i]) // 检查不能为空
|
||||||
|
{
|
||||||
|
|
||||||
|
args[i] = Activator.CreateInstance(type); // 值类型返回默认值
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isCanInvoke = false; // 参数不能为空,终止调用
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
jsonData = new JObject()
|
#endregion
|
||||||
|
#region 引用类型参数
|
||||||
|
else if (type.IsClass)
|
||||||
|
{
|
||||||
|
var jsonValue = context.MsgData.GetValue(argName);
|
||||||
|
if (!(jsonValue is null))
|
||||||
{
|
{
|
||||||
[MsgIdJsonKey] = msgId,
|
args[i] = jsonValue.ToObject(type);
|
||||||
[ThemeJsonKey] = theme,
|
}
|
||||||
[DataJsonKey] = dataToken
|
else
|
||||||
};
|
{
|
||||||
|
if (config.ArgNotNull && !config.IsCheckArgNotNull[i])
|
||||||
|
{
|
||||||
}
|
|
||||||
|
|
||||||
var msg = jsonData.ToString();
|
args[i] = null; // 引用类型返回null
|
||||||
|
}
|
||||||
|
else
|
||||||
await sendAsync.Invoke(msg);
|
{
|
||||||
|
isCanInvoke = false; // 参数不能为空,终止调用
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region 传递消息委托
|
||||||
|
else if (type.IsGenericType) // 传递SendAsync委托
|
||||||
|
{
|
||||||
|
if (type.IsAssignableFrom(typeof(Func<object, Task>)))
|
||||||
|
{
|
||||||
|
args[i] = new Func<object, Task>(async data =>
|
||||||
|
{
|
||||||
|
var jsonText = JsonConvert.SerializeObject(data);
|
||||||
|
await context.SendAsync(jsonText);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (type.IsAssignableFrom(typeof(Func<string, Task>)))
|
||||||
|
{
|
||||||
|
args[i] = new Func<string, Task>(async data =>
|
||||||
|
{
|
||||||
|
await context.SendAsync(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (type.IsAssignableFrom(typeof(Action<object>)))
|
||||||
|
{
|
||||||
|
args[i] = new Action<object>(async data =>
|
||||||
|
{
|
||||||
|
var jsonText = JsonConvert.SerializeObject(data);
|
||||||
|
await context.SendAsync(jsonText);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (type.IsAssignableFrom(typeof(Action<string>)))
|
||||||
|
{
|
||||||
|
args[i] = new Action<string>(async data =>
|
||||||
|
{
|
||||||
|
var jsonText = JsonConvert.SerializeObject(data);
|
||||||
|
await context.SendAsync(jsonText);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
return isCanInvoke;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 远程环境配置
|
||||||
|
/// </summary>
|
||||||
|
public class WebSocketHandleModuleConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 有关消息ID的 Json Key
|
||||||
|
/// </summary>
|
||||||
|
public string MsgIdJsonKey { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 有关消息主题的 Json Key
|
||||||
|
/// </summary>
|
||||||
|
public string ThemeJsonKey { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 有关数据的 Json Key
|
||||||
|
/// </summary>
|
||||||
|
public string DataJsonKey { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
112
Library/Network/WebSocket/Handle/WebSocketMsgContext.cs
Normal file
112
Library/Network/WebSocket/Handle/WebSocketMsgContext.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息处理上下文
|
||||||
|
/// </summary>
|
||||||
|
public class WebSocketMsgContext
|
||||||
|
{
|
||||||
|
public WebSocketMsgContext(Func<string, Task> sendAsync)
|
||||||
|
{
|
||||||
|
this._sendAsync = sendAsync;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标记是否已经处理,如果是,则提前退出
|
||||||
|
/// </summary>
|
||||||
|
public bool Handle { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息本体(文本)
|
||||||
|
/// </summary>
|
||||||
|
public string Msg { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息本体(JObject)
|
||||||
|
/// </summary>
|
||||||
|
public JObject JsonObject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 此次消息请求的主题
|
||||||
|
/// </summary>
|
||||||
|
public string MsgTheme { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 此次消息附带的ID
|
||||||
|
/// </summary>
|
||||||
|
public string MsgId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 此次消息的数据
|
||||||
|
/// </summary>
|
||||||
|
public JObject MsgData { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
private Func<string, Task> _sendAsync;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task SendAsync(string msg)
|
||||||
|
{
|
||||||
|
await _sendAsync.Invoke(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="moduleConfig"></param>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task RepliedAsync(WebSocketHandleModuleConfig moduleConfig,
|
||||||
|
WebSocketMsgContext context,
|
||||||
|
object data)
|
||||||
|
{
|
||||||
|
JObject jsonData;
|
||||||
|
|
||||||
|
if (data is null)
|
||||||
|
{
|
||||||
|
jsonData = new JObject()
|
||||||
|
{
|
||||||
|
[moduleConfig.MsgIdJsonKey] = context.MsgId,
|
||||||
|
[moduleConfig.ThemeJsonKey] = context.MsgTheme,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JToken dataToken;
|
||||||
|
if (data is System.Collections.IEnumerable || data is Array)
|
||||||
|
{
|
||||||
|
dataToken = JArray.FromObject(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataToken = JObject.FromObject(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData = new JObject()
|
||||||
|
{
|
||||||
|
[moduleConfig.MsgIdJsonKey] = context.MsgId,
|
||||||
|
[moduleConfig.ThemeJsonKey] = context.MsgTheme,
|
||||||
|
[moduleConfig.DataJsonKey] = dataToken
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var msg = jsonData.ToString();
|
||||||
|
//Console.WriteLine($"[{msgId}] => {theme}");
|
||||||
|
await SendAsync(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ using System.Linq.Expressions;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||||
{
|
{
|
||||||
@@ -39,16 +40,14 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加消息处理与异常处理
|
/// 添加消息处理与异常处理
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="themeKeyName"></param>
|
/// <param name="moduleConfig">模块配置</param>
|
||||||
/// <param name="dataKeyName"></param>
|
|
||||||
/// <param name="msgIdKeyName"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private WebSocketHandleModule AddMyHandleModule(string themeKeyName, string dataKeyName, string msgIdKeyName)
|
private WebSocketHandleModule AddMyHandleModule(WebSocketHandleModuleConfig moduleConfig)
|
||||||
{
|
{
|
||||||
var key = (themeKeyName, dataKeyName);
|
var key = (moduleConfig.ThemeJsonKey, moduleConfig.DataJsonKey);
|
||||||
if (!MyHandleModuleDict.TryGetValue(key, out var myHandleModule))
|
if (!MyHandleModuleDict.TryGetValue(key, out var myHandleModule))
|
||||||
{
|
{
|
||||||
myHandleModule = new WebSocketHandleModule(themeKeyName, dataKeyName, msgIdKeyName);
|
myHandleModule = new WebSocketHandleModule(moduleConfig);
|
||||||
MyHandleModuleDict[key] = myHandleModule;
|
MyHandleModuleDict[key] = myHandleModule;
|
||||||
}
|
}
|
||||||
return myHandleModule;
|
return myHandleModule;
|
||||||
@@ -95,34 +94,75 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
var themeKey = moduleAttribute.ThemeKey;
|
var themeKey = moduleAttribute.ThemeKey;
|
||||||
var dataKey = moduleAttribute.DataKey;
|
var dataKey = moduleAttribute.DataKey;
|
||||||
var msgIdKey = moduleAttribute.MsgIdKey;
|
var msgIdKey = moduleAttribute.MsgIdKey;
|
||||||
|
var moduleConfig = new WebSocketHandleModuleConfig()
|
||||||
var handleModule = AddMyHandleModule(themeKey, dataKey, msgIdKey);
|
{
|
||||||
var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
ThemeJsonKey = themeKey,
|
||||||
.Select(method =>
|
DataJsonKey = dataKey,
|
||||||
|
MsgIdJsonKey = msgIdKey,
|
||||||
|
};
|
||||||
|
|
||||||
|
var handleModule = AddMyHandleModule(moduleConfig);
|
||||||
|
var configs = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||||
|
.Select<MethodInfo, WebSocketHandleConfiguration>(methodInfo =>
|
||||||
{
|
{
|
||||||
var methodsAttribute = method.GetCustomAttribute<AutoSocketHandleAttribute>();
|
var methodsAttribute = methodInfo.GetCustomAttribute<AutoSocketHandleAttribute>();
|
||||||
if (methodsAttribute is null)
|
if (methodsAttribute is null)
|
||||||
{
|
{
|
||||||
return (null, null,false);
|
return null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(methodsAttribute.ThemeValue))
|
if (string.IsNullOrEmpty(methodsAttribute.ThemeValue))
|
||||||
{
|
{
|
||||||
methodsAttribute.ThemeValue = method.Name;
|
methodsAttribute.ThemeValue = methodInfo.Name;
|
||||||
}
|
}
|
||||||
var model = new SocketHandleModule
|
|
||||||
|
#region 生成处理配置
|
||||||
|
var config = new WebSocketHandleConfiguration
|
||||||
{
|
{
|
||||||
IsReturnValue = methodsAttribute.IsReturnValue,
|
IsReturnValue = methodsAttribute.IsReturnValue,
|
||||||
ThemeValue = methodsAttribute.ThemeValue,
|
ThemeValue = methodsAttribute.ThemeValue,
|
||||||
|
ArgNotNull = methodsAttribute.ArgNotNull,
|
||||||
};
|
};
|
||||||
|
var parameterInfos = methodInfo.GetParameters();
|
||||||
|
|
||||||
|
config.DelegateDetails = new DelegateDetails(methodInfo); // 对应theme的emit构造委托调用工具类
|
||||||
|
config.Instance = socketControlBase; // 调用emit委托时的实例
|
||||||
|
config.OnExceptionTracking = onExceptionTracking; // 异常追踪
|
||||||
|
config.ParameterType = parameterInfos.Select(t => t.ParameterType).ToArray(); // 入参参数类型
|
||||||
|
config.ParameterName = parameterInfos.Select(t => t.Name).ToArray(); // 入参参数名称
|
||||||
|
config.UseData = parameterInfos.Select(p => p.GetCustomAttribute<UseDataAttribute>() != null).ToArray(); // 是否使用整体data数据
|
||||||
|
config.UseMsgId = parameterInfos.Select(p => p.GetCustomAttribute<UseMsgIdAttribute>() != null).ToArray(); // 是否使用消息ID
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
config.IsCheckArgNotNull = parameterInfos.Select(p => p.GetCustomAttribute<NotNullAttribute>() != null).ToArray(); // 是否检查null
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (config.IsCheckArgNotNull is null)
|
||||||
|
{
|
||||||
|
config.IsCheckArgNotNull = parameterInfos.Select(p => p.GetCustomAttribute<NeedfulAttribute>() != null).ToArray(); // 是否检查null
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 兼容两种非空特性的写法
|
||||||
|
var argNotNull = parameterInfos.Select(p => p.GetCustomAttribute<NeedfulAttribute>() != null).ToArray(); // 是否检查null
|
||||||
|
for (int i = 0; i < config.IsCheckArgNotNull.Length; i++)
|
||||||
|
{
|
||||||
|
if (!config.IsCheckArgNotNull[i] && argNotNull[i])
|
||||||
|
{
|
||||||
|
config.IsCheckArgNotNull[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
var value = methodsAttribute.ThemeValue;
|
var value = methodsAttribute.ThemeValue;
|
||||||
var argNotNull = methodsAttribute.ArgNotNull;
|
|
||||||
return (model, method, argNotNull);
|
return config;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.Where(x => !(x.model is null)).ToList();
|
.Where(config => config != null).ToList();
|
||||||
if (methods.Count == 0)
|
if (configs.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,23 +171,10 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
|
|
||||||
Console.WriteLine($"add websocket handle model :");
|
Console.WriteLine($"add websocket handle model :");
|
||||||
Console.WriteLine($"theme key, data key : {themeKey}, {dataKey}");
|
Console.WriteLine($"theme key, data key : {themeKey}, {dataKey}");
|
||||||
foreach ((var module, var method,var argNotNull) in methods)
|
foreach (var config in configs)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"theme value : {module.ThemeValue}");
|
Console.WriteLine($"theme value : {config.ThemeValue} ");
|
||||||
try
|
var result = handleModule.AddHandleConfigs(config);
|
||||||
{
|
|
||||||
var jsonMsgHandleConfig = new JsonMsgHandleConfig(module, socketControlBase, method, onExceptionTracking, argNotNull);
|
|
||||||
var result = handleModule.AddHandleConfigs(module,jsonMsgHandleConfig);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
throw new Exception("添加失败,已经添加过相同的配置");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
|
|
||||||
Console.WriteLine($"error in add method: {method.Name}{Environment.NewLine}{ex}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -155,20 +182,21 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步处理消息
|
/// 异步处理消息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sendAsync"></param>
|
/// <param name="context">此次请求的上下文</param>
|
||||||
/// <param name="message"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void HandleMsg(Func<string, Task> sendAsync, string message)
|
public void HandleMsg(WebSocketMsgContext context)
|
||||||
{
|
{
|
||||||
JObject json = JObject.Parse(message);
|
// OnExceptionTracking
|
||||||
foreach (var module in MyHandleModuleDict.Values)
|
foreach (var module in MyHandleModuleDict.Values)
|
||||||
{
|
{
|
||||||
module.HandleSocketMsg(sendAsync, json);
|
module.HandleSocketMsg(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System.Text;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Serein.Library.Network.WebSocketCommunication
|
namespace Serein.Library.Network.WebSocketCommunication
|
||||||
{
|
{
|
||||||
@@ -60,10 +61,10 @@ namespace Serein.Library.Network.WebSocketCommunication
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task SendAsync(string message)
|
public async Task SendAsync(string message)
|
||||||
{
|
{
|
||||||
Console.WriteLine("发送消息");
|
//Console.WriteLine("发送消息");
|
||||||
await Task.Delay(2000);
|
//await Task.Delay(2000);
|
||||||
await SocketExtension.SendAsync(this._client, message); // 回复客户端
|
await SocketExtension.SendAsync(this._client, message); // 回复客户端
|
||||||
Console.WriteLine();
|
//Console.WriteLine();
|
||||||
//var buffer = Encoding.UTF8.GetBytes(message);
|
//var buffer = Encoding.UTF8.GetBytes(message);
|
||||||
//await _client.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
//await _client.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||||
}
|
}
|
||||||
@@ -132,15 +133,17 @@ namespace Serein.Library.Network.WebSocketCommunication
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var message = await msgQueueUtil.WaitMsgAsync(); // 有消息时通知
|
var message = await msgQueueUtil.WaitMsgAsync(); // 有消息时通知
|
||||||
//if (!msgQueueUtil.TryGetMsg(out var message)) // 获取消息
|
|
||||||
//{
|
|
||||||
// return;
|
_ = Task.Run(() => {
|
||||||
//}
|
JObject json = JObject.Parse(message);
|
||||||
// 消息处理
|
WebSocketMsgContext context = new WebSocketMsgContext(async (text) =>
|
||||||
MsgHandleHelper.HandleMsg(async (text) =>
|
{
|
||||||
{
|
await SocketExtension.SendAsync(webSocket, text); // 回复客户端,处理方法中入参如果需要发送消息委托,则将该回调方法作为委托参数传入
|
||||||
await SocketExtension.SendAsync(webSocket, text); // 回复客户端,处理方法中入参如果需要发送消息委托,则将该回调方法作为委托参数传入
|
});
|
||||||
}, message); // 处理消息
|
context.JsonObject = json;
|
||||||
|
MsgHandleHelper.HandleMsg(context); // 处理消息
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ namespace Serein.Library.Network.WebSocketCommunication
|
|||||||
}
|
}
|
||||||
|
|
||||||
var webSocketContext = await context.AcceptWebSocketAsync(null); //新连接
|
var webSocketContext = await context.AcceptWebSocketAsync(null); //新连接
|
||||||
_ = HandleWebSocketAsync(webSocketContext.WebSocket, authorizedHelper); // 处理消息
|
_ = HandleWebSocketAsync(webSocketContext.WebSocket, authorizedHelper); // 处理消息
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -231,17 +231,13 @@ namespace Serein.Library.Network.WebSocketCommunication
|
|||||||
|
|
||||||
|
|
||||||
public async Task HandleMsgAsync(WebSocket webSocket,
|
public async Task HandleMsgAsync(WebSocket webSocket,
|
||||||
MsgQueueUtil msgQueueUtil,
|
MsgQueueUtil msgQueueUtil,
|
||||||
WebSocketAuthorizedHelper authorizedHelper)
|
WebSocketAuthorizedHelper authorizedHelper)
|
||||||
{
|
{
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var message = await msgQueueUtil.WaitMsgAsync(); // 有消息时通知
|
var message = await msgQueueUtil.WaitMsgAsync(); // 有消息时通知
|
||||||
//if (!msgQueueUtil.TryGetMsg(out var message)) // 获取消息
|
|
||||||
//{
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
if (IsCheckToken)
|
if (IsCheckToken)
|
||||||
{
|
{
|
||||||
var authorizedResult = await authorizedHelper.HandleAuthorized(message); // 尝试检测授权
|
var authorizedResult = await authorizedHelper.HandleAuthorized(message); // 尝试检测授权
|
||||||
@@ -255,11 +251,17 @@ namespace Serein.Library.Network.WebSocketCommunication
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 消息处理
|
|
||||||
MsgHandleHelper.HandleMsg(async (text) =>
|
_ = Task.Run(() => {
|
||||||
{
|
JObject json = JObject.Parse(message);
|
||||||
await SocketExtension.SendAsync(webSocket, text); // 回复客户端,处理方法中入参如果需要发送消息委托,则将该回调方法作为委托参数传入
|
WebSocketMsgContext context = new WebSocketMsgContext(async (text) =>
|
||||||
}, message); // 处理消息
|
{
|
||||||
|
await SocketExtension.SendAsync(webSocket, text); // 回复客户端,处理方法中入参如果需要发送消息委托,则将该回调方法作为委托参数传入
|
||||||
|
});
|
||||||
|
context.JsonObject = json;
|
||||||
|
MsgHandleHelper.HandleMsg(context); // 处理消息
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace Serein.Library.Utils
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
var msg = jsonData.ToString();
|
var msg = jsonData.ToString();
|
||||||
Console.WriteLine($"[{msgId}] => {theme}");
|
//Console.WriteLine($"[{msgId}] => {theme}");
|
||||||
await EnvClient.SendAsync(msg);
|
await EnvClient.SendAsync(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,9 +182,6 @@ namespace Serein.Workbench
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitFlowEnvironmentEvent()
|
private void InitFlowEnvironmentEvent()
|
||||||
{
|
{
|
||||||
|
|
||||||
// 获取实现类的类型
|
|
||||||
var implementationType = EnvDecorator.CurrentEnv.GetType().Name;
|
|
||||||
EnvDecorator.OnDllLoad += FlowEnvironment_DllLoadEvent;
|
EnvDecorator.OnDllLoad += FlowEnvironment_DllLoadEvent;
|
||||||
EnvDecorator.OnProjectLoaded += FlowEnvironment_OnProjectLoaded;
|
EnvDecorator.OnProjectLoaded += FlowEnvironment_OnProjectLoaded;
|
||||||
EnvDecorator.OnStartNodeChange += FlowEnvironment_StartNodeChangeEvent;
|
EnvDecorator.OnStartNodeChange += FlowEnvironment_StartNodeChangeEvent;
|
||||||
@@ -2604,9 +2601,13 @@ namespace Serein.Workbench
|
|||||||
if (isConnect)
|
if (isConnect)
|
||||||
{
|
{
|
||||||
// 连接成功,加载远程项目
|
// 连接成功,加载远程项目
|
||||||
var flowEnvInfo = await EnvDecorator.GetEnvInfoAsync();
|
_ = Task.Run(async () =>
|
||||||
await Task.Delay(1000);
|
{
|
||||||
EnvDecorator.LoadProject(flowEnvInfo, string.Empty);// 加载远程环境的项目
|
var flowEnvInfo = await EnvDecorator.GetEnvInfoAsync();
|
||||||
|
EnvDecorator.LoadProject(flowEnvInfo, string.Empty);// 加载远程环境的项目
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
windowEnvRemoteLoginView.Show();
|
windowEnvRemoteLoginView.Show();
|
||||||
|
|||||||
Reference in New Issue
Block a user