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 { /// /// /// public class JsonMsgHandleConfig { public Guid HandleGuid { get; } internal JsonMsgHandleConfig(SocketHandleModule model, ISocketHandleModule instance, MethodInfo methodInfo, Action> 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() != null).ToArray(); this.useMsgId = parameterInfos.Select(p => p.GetCustomAttribute() != null).ToArray(); #if NET5_0_OR_GREATER this.IsCheckArgNotNull = parameterInfos.Select(p => p.GetCustomAttribute() != null).ToArray(); #endif if(IsCheckArgNotNull is null) { IsCheckArgNotNull = parameterInfos.Select(p => p.GetCustomAttribute() != null).ToArray(); } else { // 兼容两种非空特性的写法 var argNotNull = parameterInfos.Select(p => p.GetCustomAttribute() != null).ToArray(); for (int i = 0; i < IsCheckArgNotNull.Length; i++) { if (!IsCheckArgNotNull[i] && argNotNull[i]) { IsCheckArgNotNull[i] = true; } } } } /// /// 参数不能为空 /// private bool ArgNotNull; /// /// Emit委托 /// private readonly DelegateDetails DelegateDetails; /// /// 未捕获的异常跟踪 /// private readonly Action> OnExceptionTracking; /// /// 所在的模块 /// private readonly SocketHandleModule Module; /// /// 所使用的实例 /// private readonly ISocketHandleModule Instance; /// /// 参数名称 /// private readonly string[] ParameterName; /// /// 参数类型 /// private readonly Type[] ParameterType; /// /// 是否使Data整体内容作为入参参数 /// private readonly bool[] useData; /// /// 是否使用消息ID作为入参参数 /// private readonly bool[] useMsgId; /// /// 是否检查变量为空 /// private readonly bool[] IsCheckArgNotNull; public async void Handle(Func 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))) { args[i] = new Func(async data => { var jsonText = JsonConvert.SerializeObject(data); await SendAsync.Invoke(jsonText); }); } else if (type.IsAssignableFrom(typeof(Func))) { args[i] = new Func(async data => { await SendAsync.Invoke(data); }); } else if (type.IsAssignableFrom(typeof(Action))) { args[i] = new Action(async data => { var jsonText = JsonConvert.SerializeObject(data); await SendAsync.Invoke(jsonText); }); } else if (type.IsAssignableFrom(typeof(Action))) { args[i] = new Action(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); } } } }