mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-20 08:16:34 +08:00
增强了实例工程的抽象逻辑
This commit is contained in:
@@ -30,6 +30,7 @@ namespace Serein.Library.Api
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
ISereinIOC Register<TService, TImplementation>(params object[] parameters) where TImplementation : TService;
|
||||
|
||||
///// <summary>
|
||||
///// 获取或创建并注入目标类型,会记录到IOC容器中。
|
||||
///// </summary>
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Serein.Library.Entity
|
||||
/// <summary>
|
||||
/// 是否保护参数
|
||||
/// </summary>
|
||||
public bool IsProtectionParameter { get; set; } = true;
|
||||
public bool IsProtectionParameter { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 作用实例的类型
|
||||
|
||||
@@ -8,11 +8,19 @@ namespace Serein.Library.Ex
|
||||
/// </summary>
|
||||
public class FlipflopException: Exception
|
||||
{
|
||||
|
||||
public enum CancelClass
|
||||
{
|
||||
// 取消当前分支的继续执行
|
||||
Branch,
|
||||
// 取消整个触发器流程的再次执行
|
||||
Flow,
|
||||
}
|
||||
public bool IsCancel { get; }
|
||||
public FlipflopException(string message, bool isCancel = true) :base(message)
|
||||
public CancelClass Clsss { get; }
|
||||
public FlipflopException(string message, bool isCancel = true,CancelClass clsss = CancelClass.Branch) :base(message)
|
||||
{
|
||||
IsCancel = isCancel;
|
||||
Clsss = clsss;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +341,15 @@ namespace Serein.Library.Web
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject(value.ToString(), targetType);
|
||||
if (targetType == typeof(string))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonConvert.DeserializeObject(value.ToString(), targetType);
|
||||
}
|
||||
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
{
|
||||
10
Library/Network/WebSocket/WebSocketRouter.cs
Normal file
10
Library/Network/WebSocket/WebSocketRouter.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Serein.Library.Network.WebSocketCommunication
|
||||
{
|
||||
public class WebSocketRouter
|
||||
{
|
||||
}
|
||||
}
|
||||
57
Library/Network/WebSocket/WebSocketServer.cs
Normal file
57
Library/Network/WebSocket/WebSocketServer.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.Library.Network.WebSocketCommunication
|
||||
{
|
||||
public class WebSocketServer
|
||||
{
|
||||
public Func<string,Action> OnReceiveMsg;
|
||||
|
||||
public async Task StartAsync(string url)
|
||||
{
|
||||
HttpListener listener = new HttpListener();
|
||||
listener.Prefixes.Add(url);
|
||||
listener.Start();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var context = await listener.GetContextAsync();
|
||||
if (context.Request.IsWebSocketRequest)
|
||||
{
|
||||
var webSocketContext = await context.AcceptWebSocketAsync(null); //新连接
|
||||
_ = HandleWebSocketAsync(webSocketContext.WebSocket); // 处理消息
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleWebSocketAsync(WebSocket webSocket)
|
||||
{
|
||||
var buffer = new byte[1024];
|
||||
while (webSocket.State == WebSocketState.Open)
|
||||
{
|
||||
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
|
||||
Console.WriteLine($"Received: {message}");
|
||||
var action = OnReceiveMsg.Invoke(message);
|
||||
action?.Invoke();
|
||||
|
||||
// 回显消息(可选)
|
||||
//ar echoMessage = Encoding.UTF8.GetBytes(message);
|
||||
//await webSocket.SendAsync(new ArraySegment<byte>(echoMessage, 0, echoMessage.Length), result.MessageType, result.EndOfMessage, CancellationToken.None);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,12 @@ namespace Serein.Library.Attributes
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class DynamicFlowAttribute : Attribute
|
||||
{
|
||||
public DynamicFlowAttribute(bool scan = true)
|
||||
public DynamicFlowAttribute(string name = "",bool scan = true)
|
||||
{
|
||||
Name = name;
|
||||
Scan = scan;
|
||||
}
|
||||
public string Name { get; set; }
|
||||
public bool Scan { get; set; } = true;
|
||||
}
|
||||
|
||||
@@ -70,7 +72,7 @@ namespace Serein.Library.Attributes
|
||||
// }
|
||||
//}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class BindValueAttribute : Attribute
|
||||
{
|
||||
public object Value { get; }
|
||||
|
||||
@@ -33,10 +33,15 @@ namespace Serein.Library.NodeFlow.Tool
|
||||
{
|
||||
// 使用并发字典管理每个枚举信号对应的 Channel
|
||||
private readonly ConcurrentDictionary<TSignal, Channel<TriggerData>> _channels = new ConcurrentDictionary<TSignal, Channel<TriggerData>>();
|
||||
|
||||
|
||||
// 到期后自动触发。短时间内触发频率过高的情况下,请将 outTime 设置位短一些的时间,因为如果超时等待时间过长,会导致非预期的“托管内存泄露”。
|
||||
|
||||
/// <summary>
|
||||
/// 获取或创建指定信号的 Channel
|
||||
/// </summary>
|
||||
/// <param name="signal">枚举信号标识符</param>
|
||||
/// <returns>对应的 Channel</returns>
|
||||
private Channel<TriggerData> GetOrCreateChannel(TSignal signal)
|
||||
{
|
||||
return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded<TriggerData>());
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建信号并指定超时时间的Channel.
|
||||
/// </summary>
|
||||
@@ -96,6 +101,7 @@ namespace Serein.Library.NodeFlow.Tool
|
||||
Type = TriggerType.External,
|
||||
};
|
||||
// 手动触发信号
|
||||
|
||||
channel.Writer.TryWrite(triggerData);
|
||||
return true;
|
||||
}
|
||||
@@ -114,14 +120,6 @@ namespace Serein.Library.NodeFlow.Tool
|
||||
_channels.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或创建指定信号的 Channel
|
||||
/// </summary>
|
||||
/// <param name="signal">枚举信号标识符</param>
|
||||
/// <returns>对应的 Channel</returns>
|
||||
private Channel<TriggerData> GetOrCreateChannel(TSignal signal)
|
||||
{
|
||||
return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded<TriggerData>());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,16 @@ namespace Serein.Library.Utils
|
||||
{
|
||||
public static class EnumHelper
|
||||
{
|
||||
public static bool TryConvertEnum<T>(this string value, out T result) where T : struct, Enum
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, true, out T tempResult) && Enum.IsDefined(typeof(T), tempResult))
|
||||
{
|
||||
result = tempResult;
|
||||
return true;
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
public static TResult GetBoundValue<TEnum, TResult>(TEnum enumValue, Func<BindValueAttribute, object> valueSelector)
|
||||
where TEnum : Enum
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user