先想到这吧

This commit is contained in:
fengjiayi
2024-09-25 22:20:23 +08:00
parent c67315990b
commit e81c527086
26 changed files with 362 additions and 446 deletions

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Serein.Library.Entity
{
// 每次发生调用的时候,将当前节点调用信息拷贝一份,
// 调用完成后释放?
// 参数信息
public class CallChainInfo
{
public List<string> CallGuid { get; }
public List<object[]> InvokeData { get; }
public List<object> ResultData { get; }
}
}

View File

@@ -19,6 +19,10 @@ namespace Serein.Library.Entity
/// 是否为显式参数(固定值/表达式)
/// </summary>
public bool IsExplicitData { get; set; }
/// <summary>
/// 是否为值转换器
/// </summary>
public bool IsEnumConvertor { get; set; }
///// <summary>
///// 显式类型
///// </summary>
@@ -45,7 +49,7 @@ namespace Serein.Library.Entity
public string DataValue { get; set; }
public string[] Items { get; set; }
public object[] Items { get; set; }
public ExplicitData Clone() => new ExplicitData()
{

View File

@@ -37,7 +37,7 @@ namespace Serein.Library.Entity
/// <summary>
/// 是否保护参数
/// </summary>
public bool IsProtectionParameter { get; set; }
public bool IsProtectionParameter { get; set; } = true;
/// <summary>
/// 作用实例的类型

View File

@@ -49,4 +49,99 @@ namespace Serein.Library.Attributes
public string LockName;
}
//[AttributeUsage(AttributeTargets.Field)]
//public class BindTypeAttribute : Attribute
//{
// public Type Type { get; }
// public BindTypeAttribute(Type type)
// {
// Type = type;
// }
//}
[AttributeUsage(AttributeTargets.Field)]
public class BindValueAttribute : Attribute
{
public object Value { get; }
public BindValueAttribute(object value)
{
Value = value;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class PLCValueAttribute : Attribute
{
public enum VarType
{
/// <summary>
/// 可写入值
/// </summary>
Write,
/// <summary>
/// 定时读取的可写入值(用来写入前判断),应该几乎不会有这种类型?
/// </summary>
TimingReadOrWrite,
/// <summary>
/// 只读取值(使用时刷新)
/// </summary>
ReadOnly,
/// <summary>
/// 定时刷新的只读取值(定时刷新用来触发触发器)
/// </summary>
TimingReadOnly,
}
public bool IsProtected { get; }
public Type DataType { get; }
public string Var { get; }
//public int Length { get; }
//public double Offset { get; }
public VarType Type { get; }
//public int RefreshInterval { get; }
public PLCValueAttribute(Type type,
string @var,
VarType varType
//int refreshInterval = 100
)
{
DataType = type;
Var = @var;
//Offset = offset;
//RefreshInterval = refreshInterval;
Type = varType;
//Length = length;
}
}
/// <summary>
/// 枚举值转换器
/// </summary>
//[AttributeUsage(AttributeTargets.Parameter)]
//public class EnumConvertorAttribute : Attribute
//{
// public Type Enum { get; }
// public EnumConvertorAttribute(Type @enum)
// {
// if (@enum.IsEnum)
// {
// Enum = @enum;
// }
// else
// {
// throw new ArgumentException("需要枚举类型");
// }
// }
//}
}

View File

@@ -46,39 +46,38 @@ namespace Serein.Library.NodeFlow.Tool
public async Task<TriggerData> CreateChannelWithTimeoutAsync<TResult>(TSignal signal, TimeSpan outTime, TResult outValue)
{
var channel = GetOrCreateChannel(signal);
//var cts = new CancellationTokenSource();
//// 异步任务:超时后自动触发信号
//_ = Task.Run(async () =>
//{
// try
// {
// await Task.Delay(outTime, cts.Token);
// if(!cts.IsCancellationRequested) // 如果还没有被取消
// {
// TriggerData triggerData = new TriggerData()
// {
// Value = outValue,
// Type = TriggerType.Overtime,
// };
// await channel.Writer.WriteAsync(triggerData);
// }
// }
// catch (OperationCanceledException)
// {
// // 超时任务被取消
// }
// finally
// {
// cts?.Cancel();
// cts?.Dispose(); // 确保 cts 被释放
// }
//}, cts.Token);
var cts = new CancellationTokenSource();
// 异步任务:超时后自动触发信号
_ = Task.Run(async () =>
{
try
{
await Task.Delay(outTime, cts.Token);
if(!cts.IsCancellationRequested) // 如果还没有被取消
{
TriggerData triggerData = new TriggerData()
{
Value = outValue,
Type = TriggerType.Overtime,
};
await channel.Writer.WriteAsync(triggerData);
}
}
catch (OperationCanceledException)
{
// 超时任务被取消
}
finally
{
cts?.Cancel();
cts?.Dispose(); // 确保 cts 被释放
}
}, cts.Token);
// 等待信号传入(超时或手动触发)
var result = await channel.Reader.ReadAsync();
//cts?.Cancel();
//cts?.Dispose();
cts?.Cancel();
return result;
}

View File

@@ -0,0 +1,35 @@
using Serein.Library.Attributes;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Serein.Library.Utils
{
public static class EnumHelper
{
public static TResult GetBoundValue<TEnum, TResult>(TEnum enumValue, Func<BindValueAttribute, object> valueSelector)
where TEnum : Enum
{
var fieldInfo = typeof(TEnum).GetField(enumValue.ToString());
var attribute = fieldInfo.GetCustomAttribute<BindValueAttribute>();
return attribute != null ? (TResult)valueSelector(attribute) : default;
}
//public static TResult GetBoundValue<TEnum, TAttribute, TResult>(TEnum enumValue,
// Func<TAttribute, TResult> valueSelector)
// where TEnum : Enum
// where TAttribute : Attribute
//{
// var fieldInfo = typeof(TEnum).GetField(enumValue.ToString());
// var attribute = fieldInfo.GetCustomAttribute<TAttribute>();
// return attribute != null ? valueSelector(attribute) : default;
//}
}
}

View File

@@ -21,7 +21,7 @@ namespace Serein.Library.Web
public interface IRouter
{
bool RegisterController(Type controllerType);
Task ProcessingAsync(HttpListenerContext context);
Task<bool> ProcessingAsync(HttpListenerContext context);
}
/// <summary>
@@ -75,7 +75,7 @@ namespace Serein.Library.Web
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task ProcessingAsync(HttpListenerContext context)
public async Task<bool> ProcessingAsync(HttpListenerContext context)
{
var request = context.Request; // 获取请求对象
var response = context.Response; // 获取响应对象
@@ -84,16 +84,16 @@ namespace Serein.Library.Web
var template = request.Url.AbsolutePath.ToLower();
if (!_routes[httpMethod].TryGetValue(template, out MethodInfo method))
{
return;
return false;
}
var routeValues = GetUrlData(url); // 解析 URL 获取路由参数
ControllerBase controllerInstance = (ControllerBase)SereinIOC.Instantiate(_controllerTypes[template]);// 使用反射创建控制器实例
if (controllerInstance == null)
if (controllerInstance is null)
{
return; // 未找到控制器实例
return false; // 未找到控制器实例
}
controllerInstance.Url = url.AbsolutePath;
@@ -119,11 +119,13 @@ namespace Serein.Library.Web
break;
}
Return(response, result); // 返回结果
return true;
}
catch (Exception ex)
{
response.StatusCode = (int)HttpStatusCode.NotFound; // 返回 404 错误
Return(response, ex.Message); // 返回结果
return true;
}
}
@@ -146,7 +148,7 @@ namespace Serein.Library.Web
{
var url = AddRoutesUrl(autoHostingAttribute, routeAttribute, controllerType, method);
Console.WriteLine(url);
if (url == null) continue;
if (url is null) continue;
_controllerTypes[url] = controllerType;
}
}
@@ -211,7 +213,7 @@ namespace Serein.Library.Web
/// </summary>
public object InvokeControllerMethod(MethodInfo method, object controllerInstance, JObject requestData, Dictionary<string, string> routeValues)
{
if (requestData == null) return null;
if (requestData is null) return null;
ParameterInfo[] parameters;
object[] cachedMethodParameters;
if (!methodParameterCache.TryGetValue(method, out parameters))
@@ -355,7 +357,6 @@ namespace Serein.Library.Web
{
return value;
}
#pragma warning restore CS0168 // 声明了变量,但从未使用过
}
/// <summary>
@@ -554,7 +555,7 @@ namespace Serein.Library.Web
}
return null;
}
}
#endregion
}
@@ -562,7 +563,7 @@ namespace Serein.Library.Web
internal static class WebFunc
{
public static bool ToBool(this JToken token,bool defult = false)
public static bool ToBool(this JToken token, bool defult = false)
{
var value = token?.ToString();
if (string.IsNullOrWhiteSpace(value))

View File

@@ -100,18 +100,22 @@ namespace Serein.Library.Web
}
var isPass = requestLimiter.AllowRequest(context.Request);
if (!isPass)
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound; // 返回 404 错误
}
isPass = await Router.ProcessingAsync(context); // 路由解析
if (isPass)
{
// 如果路由没有匹配,会返回 404
await Router.ProcessingAsync(context); // 路由解析
context.Response.StatusCode = (int)HttpStatusCode.OK; // 返回 404 错误
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound; // 返回 404 错误
context.Response.Close(); // 关闭响应
}
// var request = context.Request;
context.Response.Close(); // 关闭响应
// var request = context.Request;
// 获取远程终结点信息
var remoteEndPoint = context.Request.RemoteEndPoint;
// 获取用户的IP地址和端口