mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-03 00:00:49 +08:00
先想到这吧
This commit is contained in:
18
Library/Entity/CallChainInfo.cs
Normal file
18
Library/Entity/CallChainInfo.cs
Normal 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; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Serein.Library.Entity
|
||||
/// <summary>
|
||||
/// 是否保护参数
|
||||
/// </summary>
|
||||
public bool IsProtectionParameter { get; set; }
|
||||
public bool IsProtectionParameter { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 作用实例的类型
|
||||
|
||||
@@ -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("需要枚举类型");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
35
Library/Utils/EnumHelper.cs
Normal file
35
Library/Utils/EnumHelper.cs
Normal 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;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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地址和端口
|
||||
|
||||
Reference in New Issue
Block a user