mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-04 07:16:35 +08:00
修改了很多
This commit is contained in:
@@ -42,7 +42,8 @@ namespace Serein.Library.Api
|
||||
/// <summary>
|
||||
/// 用以提前结束分支运行
|
||||
/// </summary>
|
||||
void EndCurrentBranch();
|
||||
void Exit();
|
||||
|
||||
|
||||
/*/// <summary>
|
||||
/// 定时循环触发
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
|
||||
using Serein.Library.FlowNode;
|
||||
using Serein.Library.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -176,6 +177,15 @@ namespace Serein.Library.Api
|
||||
/// </summary>
|
||||
Remote,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更改方法调用关系
|
||||
/// </summary>
|
||||
/// <param name="fromNodeGuid"></param>
|
||||
/// <param name="toNodeGuid"></param>
|
||||
/// <param name="junctionOfConnectionType"></param>
|
||||
/// <param name="connectionInvokeType"></param>
|
||||
/// <param name="changeType"></param>
|
||||
public NodeConnectChangeEventArgs(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionOfConnectionType junctionOfConnectionType, // 指示需要创建什么类型的连接线
|
||||
@@ -189,6 +199,15 @@ namespace Serein.Library.Api
|
||||
this.JunctionOfConnectionType = junctionOfConnectionType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更改参数传递关系
|
||||
/// </summary>
|
||||
/// <param name="fromNodeGuid"></param>
|
||||
/// <param name="toNodeGuid"></param>
|
||||
/// <param name="junctionOfConnectionType"></param>
|
||||
/// <param name="argIndex"></param>
|
||||
/// <param name="connectionArgSourceType"></param>
|
||||
/// <param name="changeType"></param>
|
||||
public NodeConnectChangeEventArgs(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionOfConnectionType junctionOfConnectionType, // 指示需要创建什么类型的连接线
|
||||
@@ -228,6 +247,9 @@ namespace Serein.Library.Api
|
||||
/// 节点对应的方法入参所需参数来源
|
||||
/// </summary>
|
||||
public ConnectionArgSourceType ConnectionArgSourceType { get; protected set; }
|
||||
/// <summary>
|
||||
/// 第几个参数
|
||||
/// </summary>
|
||||
public int ArgIndex { get; protected set; }
|
||||
|
||||
|
||||
@@ -350,17 +372,19 @@ namespace Serein.Library.Api
|
||||
/// </summary>
|
||||
public class NodeInterruptStateChangeEventArgs : FlowEventArgs
|
||||
{
|
||||
public NodeInterruptStateChangeEventArgs(string nodeGuid, InterruptClass @class)
|
||||
public NodeInterruptStateChangeEventArgs(string nodeGuid,bool isInterrupt)
|
||||
{
|
||||
NodeGuid = nodeGuid;
|
||||
Class = @class;
|
||||
// Class = @class;
|
||||
IsInterrupt = isInterrupt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中断的节点Guid
|
||||
/// </summary>
|
||||
public string NodeGuid { get; protected set; }
|
||||
public InterruptClass Class { get; protected set; }
|
||||
public bool IsInterrupt { get; protected set; }
|
||||
// public InterruptClass Class { get; protected set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 节点触发了中断事件参数
|
||||
@@ -638,7 +662,7 @@ namespace Serein.Library.Api
|
||||
/// <param name="addres">远程环境地址</param>
|
||||
/// <param name="port">远程环境端口</param>
|
||||
/// <param name="token">密码</param>
|
||||
Task<(bool, RemoteEnvControl)> ConnectRemoteEnv(string addres,int port, string token);
|
||||
Task<(bool, RemoteMsgUtil)> ConnectRemoteEnv(string addres,int port, string token);
|
||||
|
||||
/// <summary>
|
||||
/// 退出远程环境
|
||||
@@ -705,30 +729,53 @@ namespace Serein.Library.Api
|
||||
/// <param name="toNodeGuid">目标节点Guid</param>
|
||||
/// <param name="fromNodeJunctionType">起始节点控制点</param>
|
||||
/// <param name="toNodeJunctionType">目标节点控制点</param>
|
||||
/// <param name="connectionType">决定了方法执行后的后继行为</param>
|
||||
/// <param name="argIndex">决定了方法入参来源</param>
|
||||
Task<bool> ConnectNodeAsync(string fromNodeGuid,
|
||||
/// <param name="invokeType">决定了方法执行后的后继行为</param>
|
||||
Task<bool> ConnectInvokeNodeAsync(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionType fromNodeJunctionType,
|
||||
JunctionType toNodeJunctionType,
|
||||
ConnectionInvokeType connectionType,
|
||||
int argIndex);
|
||||
ConnectionInvokeType invokeType);
|
||||
|
||||
/// <summary>
|
||||
/// 在两个节点之间创建连接关系
|
||||
/// </summary>
|
||||
/// <param name="fromNodeGuid">起始节点Guid</param>
|
||||
/// <param name="toNodeGuid">目标节点Guid</param>
|
||||
/// <param name="fromNodeJunctionType">起始节点控制点</param>
|
||||
/// <param name="toNodeJunctionType">目标节点控制点</param>
|
||||
/// <param name="argSourceType">决定了方法参数来源</param>
|
||||
/// <param name="argIndex">设置第几个参数</param>
|
||||
Task<bool> ConnectArgSourceNodeAsync(string fromNodeGuid,
|
||||
string toNodeGuid,
|
||||
JunctionType fromNodeJunctionType,
|
||||
JunctionType toNodeJunctionType,
|
||||
ConnectionArgSourceType argSourceType,
|
||||
int argIndex);
|
||||
/// <summary>
|
||||
/// 创建节点/区域/基础控件
|
||||
/// </summary>
|
||||
/// <param name="nodeType">节点/区域/基础控件类型</param>
|
||||
/// <param name="position">节点在画布上的位置(</param>
|
||||
/// <param name="methodDetailsInfo">节点绑定的方法说明(</param>
|
||||
/// <param name="methodDetailsInfo">节点绑定的方法说明</param>
|
||||
Task<NodeInfo> CreateNodeAsync(NodeControlType nodeType, PositionOfUI position, MethodDetailsInfo methodDetailsInfo = null);
|
||||
|
||||
/// <summary>
|
||||
/// 移除两个节点之间的连接关系
|
||||
/// 移除两个节点之间的方法调用关系
|
||||
/// </summary>
|
||||
/// <param name="fromNodeGuid">起始节点</param>
|
||||
/// <param name="toNodeGuid">目标节点</param>
|
||||
/// <param name="connectionType">连接类型</param>
|
||||
Task<bool> RemoveConnectAsync(string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType);
|
||||
Task<bool> RemoveConnectInvokeAsync(string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType);
|
||||
|
||||
/// <summary>
|
||||
/// 移除连接节点之间参数传递的关系
|
||||
/// </summary>
|
||||
/// <param name="fromNodeGuid">起始节点Guid</param>
|
||||
/// <param name="toNodeGuid">目标节点Guid</param>
|
||||
/// <param name="argIndex">连接到第几个参数</param>
|
||||
/// <param name="connectionArgSourceType">参数来源类型</param>
|
||||
Task<bool> RemoveConnectArgSourceAsync(string fromNodeGuid, string toNodeGuid, int argIndex);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 移除节点/区域/基础控件
|
||||
@@ -750,12 +797,12 @@ namespace Serein.Library.Api
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置节点中断级别
|
||||
/// 设置节点中断
|
||||
/// </summary>
|
||||
/// <param name="nodeGuid">被中断的节点Guid</param>
|
||||
/// <param name="interruptClass">新的中断级别</param>
|
||||
/// <param name="nodeGuid">更改中断状态的节点Guid</param>
|
||||
/// <param name="isInterrup">是否中断</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> SetNodeInterruptAsync(string nodeGuid, InterruptClass interruptClass);
|
||||
Task<bool> SetNodeInterruptAsync(string nodeGuid,bool isInterrup);
|
||||
|
||||
/// <summary>
|
||||
/// 添加作用于某个对象的中断表达式
|
||||
|
||||
78
Library/Extension/SereinExtension.cs
Normal file
78
Library/Extension/SereinExtension.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// 拓展方法
|
||||
/// </summary>
|
||||
public static partial class SereinExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 判断连接类型
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <returns></returns>
|
||||
public static JunctionOfConnectionType ToConnectyionType(this JunctionType start)
|
||||
{
|
||||
if (start == JunctionType.Execute
|
||||
|| start == JunctionType.NextStep)
|
||||
{
|
||||
return JunctionOfConnectionType.Invoke;
|
||||
}
|
||||
else
|
||||
{
|
||||
return JunctionOfConnectionType.Arg;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断是否运行连接
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsCanConnection(this JunctionType start,JunctionType end)
|
||||
{
|
||||
if(start == end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var startType = start.ToConnectyionType();
|
||||
if (startType == JunctionOfConnectionType.Invoke)
|
||||
{
|
||||
return (end == JunctionType.Execute && start == JunctionType.NextStep)
|
||||
|| (start == JunctionType.Execute && end == JunctionType.NextStep);
|
||||
}
|
||||
else // if (startType == JunctionOfConnectionType.Arg)
|
||||
{
|
||||
return (end == JunctionType.ArgData && start == JunctionType.ReturnData)
|
||||
|| (start == JunctionType.ArgData && end == JunctionType.ReturnData);
|
||||
}
|
||||
|
||||
//var endType = end.ToConnectyionType();
|
||||
//if (startType != endType
|
||||
// || startType == JunctionOfConnectionType.None
|
||||
// || endType == JunctionOfConnectionType.None)
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// if (startType == JunctionOfConnectionType.Invoke)
|
||||
// {
|
||||
|
||||
// return end == JunctionType.NextStep;
|
||||
// }
|
||||
// else // if (startType == JunctionOfConnectionType.Arg)
|
||||
// {
|
||||
// return end == JunctionType.ReturnData;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static Serein.Library.Utils.EmitHelper;
|
||||
@@ -14,6 +15,17 @@ namespace Serein.Library
|
||||
/// </summary>
|
||||
public class DelegateDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据方法信息构建Emit委托
|
||||
/// </summary>
|
||||
/// <param name="methodInfo"></param>
|
||||
public DelegateDetails(MethodInfo methodInfo)
|
||||
{
|
||||
var emitMethodType = EmitHelper.CreateDynamicMethod(methodInfo, out var emitDelegate);
|
||||
_emitMethodType = emitMethodType;
|
||||
_emitDelegate = emitDelegate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Emit委托
|
||||
/// </summary>
|
||||
@@ -21,8 +33,8 @@ namespace Serein.Library
|
||||
/// <param name="EmitDelegate"></param>
|
||||
public DelegateDetails(EmitMethodType EmitMethodType, Delegate EmitDelegate)
|
||||
{
|
||||
this._emitMethodType = EmitMethodType;
|
||||
this._emitDelegate = EmitDelegate;
|
||||
_emitMethodType = EmitMethodType;
|
||||
_emitDelegate = EmitDelegate;
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新委托方法
|
||||
@@ -56,7 +68,7 @@ namespace Serein.Library
|
||||
/// <returns>void方法自动返回null</returns>
|
||||
public async Task<object> InvokeAsync(object instance, object[] args)
|
||||
{
|
||||
if(args is null)
|
||||
if (args is null)
|
||||
{
|
||||
args = Array.Empty<object>();
|
||||
}
|
||||
@@ -35,15 +35,16 @@ namespace Serein.Library
|
||||
/// <summary>
|
||||
/// 中断级别,暂时停止继续执行后继分支。
|
||||
/// </summary>
|
||||
[PropertyInfo]
|
||||
private InterruptClass _interruptClass = InterruptClass.None;
|
||||
//[PropertyInfo]
|
||||
//private InterruptClass _interruptClass = InterruptClass.None;
|
||||
|
||||
/// <summary>
|
||||
/// 中断级别,暂时停止继续执行后继分支。
|
||||
/// </summary>
|
||||
[PropertyInfo(IsNotification = true)]
|
||||
[PropertyInfo(IsNotification = true, CustomCode = "NodeModel?.Env?.SetNodeInterruptAsync(NodeModel?.Guid, value);")]
|
||||
private bool _isInterrupt = false;
|
||||
|
||||
//private const string MyInteruptCode = "NodeModel?.Env?.SetNodeInterruptAsync(NodeModel?.Guid, value);"; // 添加到中断的自定义代码
|
||||
|
||||
/// <summary>
|
||||
/// 取消中断的回调函数
|
||||
@@ -56,29 +57,30 @@ namespace Serein.Library
|
||||
/// </summary>
|
||||
[PropertyInfo]
|
||||
private Func<Task<CancelType>> _getInterruptTask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 中断级别,暂时停止继续执行后继分支。
|
||||
/// </summary>
|
||||
//public enum InterruptClass
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 不中断
|
||||
// /// </summary>
|
||||
// None,
|
||||
// /// <summary>
|
||||
// /// 分支中断,中断进入当前节点的分支。
|
||||
// /// </summary>
|
||||
// Branch,
|
||||
// /// <summary>
|
||||
// /// 全局中断,中断全局所有节点的运行。(暂未实现相关)
|
||||
// /// </summary>
|
||||
// Global,
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 中断级别,暂时停止继续执行后继分支。
|
||||
/// </summary>
|
||||
public enum InterruptClass
|
||||
{
|
||||
/// <summary>
|
||||
/// 不中断
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// 分支中断,中断进入当前节点的分支。
|
||||
/// </summary>
|
||||
Branch,
|
||||
/// <summary>
|
||||
/// 全局中断,中断全局所有节点的运行。(暂未实现相关)
|
||||
/// </summary>
|
||||
Global,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,9 +85,6 @@ namespace Serein.Library
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public abstract partial class NodeModelBase : IDynamicFlowNode
|
||||
{
|
||||
public NodeModelBase(IFlowEnvironment environment)
|
||||
@@ -119,39 +116,40 @@ namespace Serein.Library
|
||||
/// <summary>
|
||||
/// 控制FlowData在同一时间只会被同一个线程更改。
|
||||
/// </summary>
|
||||
private readonly ReaderWriterLockSlim _flowDataLock = new ReaderWriterLockSlim();
|
||||
private object _flowData;
|
||||
/// <summary>
|
||||
/// 当前传递数据(执行了节点对应的方法,才会存在值)。
|
||||
/// </summary>
|
||||
protected object FlowData
|
||||
{
|
||||
get
|
||||
{
|
||||
_flowDataLock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return _flowData;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_flowDataLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
_flowDataLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
_flowData = value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_flowDataLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
//private readonly ReaderWriterLockSlim _flowDataLock = new ReaderWriterLockSlim();
|
||||
//private object _flowData;
|
||||
///// <summary>
|
||||
///// 当前传递数据(执行了节点对应的方法,才会存在值)。
|
||||
///// </summary>
|
||||
//protected object FlowData
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// _flowDataLock.EnterReadLock();
|
||||
// try
|
||||
// {
|
||||
// return _flowData;
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// _flowDataLock.ExitReadLock();
|
||||
// }
|
||||
// }
|
||||
// set
|
||||
// {
|
||||
// _flowDataLock.EnterWriteLock();
|
||||
// try
|
||||
// {
|
||||
// _flowData = value;
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// _flowDataLock.ExitWriteLock();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -319,5 +317,5 @@ namespace Serein.Library
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Serein.Library
|
||||
/// 获取节点参数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Parameterdata[] GetParameterdatas();
|
||||
public abstract ParameterData[] GetParameterdatas();
|
||||
|
||||
/// <summary>
|
||||
/// 导出为节点信息
|
||||
@@ -47,7 +47,7 @@ namespace Serein.Library
|
||||
var upstreamNodes = SuccessorNodes[ConnectionInvokeType.Upstream].Select(item => item.Guid);// 上游分支
|
||||
|
||||
// 生成参数列表
|
||||
Parameterdata[] parameterData = GetParameterdatas();
|
||||
ParameterData[] parameterData = GetParameterdatas();
|
||||
|
||||
return new NodeInfo
|
||||
{
|
||||
@@ -82,9 +82,13 @@ namespace Serein.Library
|
||||
{
|
||||
for (int i = 0; i < nodeInfo.ParameterData.Length; i++)
|
||||
{
|
||||
Parameterdata pd = nodeInfo.ParameterData[i];
|
||||
this.MethodDetails.ParameterDetailss[i].IsExplicitData = pd.State;
|
||||
this.MethodDetails.ParameterDetailss[i].DataValue = pd.Value;
|
||||
var mdPd = this.MethodDetails.ParameterDetailss[i];
|
||||
ParameterData pd = nodeInfo.ParameterData[i];
|
||||
mdPd.IsExplicitData = pd.State;
|
||||
mdPd.DataValue = pd.Value;
|
||||
mdPd.ArgDataSourceType = EnumHelper.ConvertEnum<ConnectionArgSourceType>(pd.SourceType);
|
||||
mdPd.ArgDataSourceNodeGuid = pd.SourceNodeGuid;
|
||||
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@@ -93,13 +97,12 @@ namespace Serein.Library
|
||||
|
||||
#region 调试中断
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 不再中断
|
||||
/// </summary>
|
||||
public void CancelInterrupt()
|
||||
{
|
||||
this.DebugSetting.InterruptClass = InterruptClass.None;
|
||||
this.DebugSetting.IsInterrupt = false;
|
||||
DebugSetting.CancelInterruptCallback?.Invoke();
|
||||
}
|
||||
|
||||
@@ -165,7 +168,7 @@ namespace Serein.Library
|
||||
NodeModelBase upstreamNode = upstreamNodes[index];
|
||||
if (!(upstreamNode is null) && upstreamNode.DebugSetting.IsEnable)
|
||||
{
|
||||
if (upstreamNode.DebugSetting.InterruptClass != InterruptClass.None) // 执行触发前
|
||||
if (upstreamNode.DebugSetting.IsInterrupt) // 执行触发前
|
||||
{
|
||||
var cancelType = await upstreamNode.DebugSetting.GetInterruptTask();
|
||||
await Console.Out.WriteLineAsync($"[{upstreamNode.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支");
|
||||
@@ -220,7 +223,7 @@ namespace Serein.Library
|
||||
{
|
||||
#region 调试中断
|
||||
|
||||
if (DebugSetting.InterruptClass != InterruptClass.None) // 执行触发检查是否需要中断
|
||||
if (DebugSetting.IsInterrupt) // 执行触发检查是否需要中断
|
||||
{
|
||||
var cancelType = await this.DebugSetting.GetInterruptTask(); // 等待中断结束
|
||||
await Console.Out.WriteLineAsync($"[{this.MethodDetails?.MethodName}]中断已{cancelType},开始执行后继分支");
|
||||
@@ -312,8 +315,9 @@ namespace Serein.Library
|
||||
}
|
||||
|
||||
object[] parameters = new object[md.ParameterDetailss.Length];
|
||||
var previousFlowData = nodeModel.PreviousNode?.FlowData; // 当前传递的数据
|
||||
var previousDataType = previousFlowData?.GetType(); // 当前传递数据的类型
|
||||
|
||||
//var previousFlowData = nodeModel.PreviousNode?.FlowData; // 当前传递的数据
|
||||
|
||||
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
@@ -336,41 +340,48 @@ namespace Serein.Library
|
||||
object inputParameter; // 存放解析的临时参数
|
||||
if (ed.IsExplicitData) // 判断是否使用显示的输入参数
|
||||
{
|
||||
if (ed.DataValue.StartsWith("@get", StringComparison.OrdinalIgnoreCase) && !(previousFlowData is null))
|
||||
if (ed.DataValue.StartsWith("@get", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var previousFlowData = context.GetFlowData(nodeModel?.PreviousNode?.Guid); // 当前传递的数据
|
||||
// 执行表达式从上一节点获取对象
|
||||
inputParameter = SerinExpressionEvaluator.Evaluate(ed.DataValue, previousFlowData, out _);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用输入的固定值
|
||||
inputParameter = ed.DataValue;
|
||||
inputParameter = ed.DataValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ed.ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData)
|
||||
{
|
||||
inputParameter = previousFlowData; // 使用运行时上一节点的返回值
|
||||
inputParameter = context.GetFlowData(nodeModel?.PreviousNode?.Guid); // 当前传递的数据
|
||||
}
|
||||
else if (ed.ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData)
|
||||
else if (ed.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeData)
|
||||
{
|
||||
// 获取指定节点的数据
|
||||
// 如果指定节点没有被执行,会返回null
|
||||
// 如果执行过,会获取上一次执行结果作为预入参数据
|
||||
inputParameter = ed.ArgDataSourceNodeMoels[i].FlowData;
|
||||
inputParameter = context.GetFlowData(ed.ArgDataSourceNodeGuid);
|
||||
}
|
||||
else if (ed.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeDataOfInvoke)
|
||||
{
|
||||
// 立刻调用对应节点获取数据。
|
||||
var result = await ed.ArgDataSourceNodeMoels[i].InvokeAsync(nodeModel.Env);
|
||||
|
||||
var result = await context.Env.InvokeNodeAsync(ed.ArgDataSourceNodeGuid);
|
||||
inputParameter = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("节点执行方法获取入参参数时,ConnectionArgSourceType枚举是意外的枚举值");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inputParameter is null)
|
||||
{
|
||||
throw new Exception($"[arg{ed.Index}][{ed.Name}][{ed.DataType}]参数不能为null");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 入参存在取值转换器,调用对应的转换器获取入参数据
|
||||
@@ -418,7 +429,7 @@ namespace Serein.Library
|
||||
#endregion
|
||||
|
||||
#region 对入参数据尝试进行转换
|
||||
|
||||
|
||||
if (inputParameter.GetType() == ed.DataType)
|
||||
{
|
||||
parameters[i] = inputParameter; // 类型一致无需转换,直接装入入参数组
|
||||
@@ -506,8 +517,8 @@ namespace Serein.Library
|
||||
{
|
||||
await MonitorObjExpInterrupt(context, nodeModel, newData, 0); // 首先监视对象
|
||||
await MonitorObjExpInterrupt(context, nodeModel, newData, 1); // 然后监视节点
|
||||
nodeModel.FlowData = newData; // 替换数据
|
||||
context.AddOrUpdate(guid, nodeModel); // 上下文中更新数据
|
||||
//nodeModel.FlowData = newData; // 替换数据
|
||||
context.AddOrUpdate(guid, newData); // 上下文中更新数据
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,12 +559,13 @@ namespace Serein.Library
|
||||
|
||||
if (isExpInterrupt) // 触发中断
|
||||
{
|
||||
InterruptClass interruptClass = InterruptClass.Branch; // 分支中断
|
||||
if (await context.Env.SetNodeInterruptAsync(nodeModel.Guid, interruptClass))
|
||||
nodeModel.DebugSetting.IsInterrupt = true;
|
||||
if (await context.Env.SetNodeInterruptAsync(nodeModel.Guid,true))
|
||||
{
|
||||
context.Env.TriggerInterrupt(nodeModel.Guid, exp, InterruptTriggerEventArgs.InterruptTriggerType.Exp);
|
||||
var cancelType = await nodeModel.DebugSetting.GetInterruptTask();
|
||||
await Console.Out.WriteLineAsync($"[{data}]中断已{cancelType},开始执行后继分支");
|
||||
nodeModel.DebugSetting.IsInterrupt = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -561,26 +573,26 @@ namespace Serein.Library
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放对象
|
||||
/// </summary>
|
||||
public void ReleaseFlowData()
|
||||
{
|
||||
if (typeof(IDisposable).IsAssignableFrom(FlowData?.GetType()) && FlowData is IDisposable disposable)
|
||||
{
|
||||
disposable?.Dispose();
|
||||
}
|
||||
this.FlowData = null;
|
||||
}
|
||||
///// <summary>
|
||||
///// 释放对象
|
||||
///// </summary>
|
||||
//public void ReleaseFlowData()
|
||||
//{
|
||||
// if (typeof(IDisposable).IsAssignableFrom(FlowData?.GetType()) && FlowData is IDisposable disposable)
|
||||
// {
|
||||
// disposable?.Dispose();
|
||||
// }
|
||||
// this.FlowData = null;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object GetFlowData()
|
||||
{
|
||||
return this.FlowData;
|
||||
}
|
||||
///// <summary>
|
||||
///// 获取节点数据
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//public object GetFlowData()
|
||||
//{
|
||||
// return this.FlowData;
|
||||
//}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
@@ -62,11 +63,10 @@ namespace Serein.Library
|
||||
|
||||
/// <summary>
|
||||
/// 当 ArgDataSourceType 不为 GetPreviousNodeData 时(从运行时上一节点获取数据)。
|
||||
/// 则通过该集合对应的节点,获取其 FlowData 作为预处理的入参参数。
|
||||
/// 则通过当前上下文,获取该Guid对应的数据作为预处理的入参参数。
|
||||
/// </summary>
|
||||
[PropertyInfo(IsProtection = true)]
|
||||
public NodeModelBase[] _argDataSourceNodeMoels;
|
||||
|
||||
[PropertyInfo]
|
||||
private string _argDataSourceNodeGuid;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -97,6 +97,16 @@ namespace Serein.Library
|
||||
|
||||
public partial class ParameterDetails
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 用于创建元数据
|
||||
/// </summary>
|
||||
public ParameterDetails()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 为节点实例化新的入参描述
|
||||
/// </summary>
|
||||
@@ -112,27 +122,15 @@ namespace Serein.Library
|
||||
/// <param name="info">参数信息</param>
|
||||
public ParameterDetails(ParameterDetailsInfo info)
|
||||
{
|
||||
//this.env = env;
|
||||
Index = info.Index;
|
||||
Name = info.Name;
|
||||
DataType = Type.GetType(info.DataTypeFullName);
|
||||
ExplicitType = Type.GetType(info.ExplicitTypeFullName);
|
||||
ExplicitTypeName = info.ExplicitTypeName;
|
||||
Items = info.Items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于创建元数据
|
||||
/// </summary>
|
||||
public ParameterDetails()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 转为描述
|
||||
/// </summary>
|
||||
@@ -141,12 +139,12 @@ namespace Serein.Library
|
||||
{
|
||||
return new ParameterDetailsInfo
|
||||
{
|
||||
Index = Index,
|
||||
DataTypeFullName = DataType.FullName,
|
||||
Name = Name,
|
||||
ExplicitTypeFullName = ExplicitType.FullName,
|
||||
ExplicitTypeName = ExplicitTypeName,
|
||||
Items = Items,
|
||||
Index = this.Index,
|
||||
DataTypeFullName = this.DataType.FullName,
|
||||
Name = this.Name,
|
||||
ExplicitTypeFullName = this.ExplicitType.FullName,
|
||||
ExplicitTypeName = this.ExplicitTypeName,
|
||||
Items = this.Items.Select(it => it).ToArray(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -154,7 +152,7 @@ namespace Serein.Library
|
||||
/// 为某个节点拷贝方法描述的入参描述
|
||||
/// </summary>
|
||||
/// <param name="env">运行环境</param>
|
||||
/// <param name="nodeGuid">运行环境</param>
|
||||
/// <param name="nodeModel">对应的节点</param>
|
||||
/// <returns></returns>
|
||||
public ParameterDetails CloneOfClone(IFlowEnvironment env, NodeModelBase nodeModel)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Serein.Library
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 方法入参描述
|
||||
/// 方法入参描述(远程用)
|
||||
/// </summary>
|
||||
public class ParameterDetailsInfo
|
||||
{
|
||||
@@ -26,6 +26,7 @@ namespace Serein.Library
|
||||
/// 方法入参参数名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 显式类型
|
||||
/// </summary>
|
||||
|
||||
@@ -202,14 +202,13 @@ namespace Serein.Library
|
||||
/// <summary>
|
||||
/// 参数
|
||||
/// </summary>
|
||||
public Parameterdata[] ParameterData { get; set; }
|
||||
public ParameterData[] ParameterData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 如果是区域控件,则会存在子项。
|
||||
/// </summary>
|
||||
public string[] ChildNodeGuids { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 于画布中的位置
|
||||
/// </summary>
|
||||
@@ -223,14 +222,26 @@ namespace Serein.Library
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示参数,项目文件相关
|
||||
/// 参数信息,项目文件相关
|
||||
/// </summary>
|
||||
public class Parameterdata
|
||||
public class ParameterData
|
||||
{
|
||||
/// <summary>
|
||||
/// 参数类型,true时使用自定义的入参,false时由运行环境自动传参
|
||||
/// </summary>
|
||||
public bool State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数来源节点
|
||||
/// </summary>
|
||||
public string SourceNodeGuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源类型
|
||||
/// </summary>
|
||||
public string SourceType { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 自定义入参
|
||||
/// </summary>
|
||||
|
||||
@@ -17,28 +17,58 @@ using Type = System.Type;
|
||||
|
||||
namespace Serein.Library.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// 路由接口
|
||||
/// </summary>
|
||||
public interface IRouter
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加处理模块
|
||||
/// </summary>
|
||||
/// <param name="controllerType"></param>
|
||||
void AddHandle(Type controllerType);
|
||||
/// <summary>
|
||||
/// 路由解析开始处理
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> ProcessingAsync(HttpListenerContext context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// api请求处理模块
|
||||
/// </summary>
|
||||
public class ApiHandleConfig
|
||||
{
|
||||
private readonly Delegate EmitDelegate;
|
||||
private readonly EmitHelper.EmitMethodType EmitMethodType;
|
||||
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)
|
||||
{
|
||||
EmitMethodType = EmitHelper.CreateDynamicMethod(methodInfo, out EmitDelegate);
|
||||
delegateDetails = new DelegateDetails(methodInfo);
|
||||
var parameterInfos = methodInfo.GetParameters();
|
||||
ParameterType = parameterInfos.Select(t => t.ParameterType).ToArray();
|
||||
ParameterName = parameterInfos.Select(t => t.Name.ToLower()).ToArray();
|
||||
@@ -68,7 +98,12 @@ namespace Serein.Library.Web
|
||||
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];
|
||||
@@ -93,40 +128,20 @@ namespace Serein.Library.Web
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object result;
|
||||
object result = null;
|
||||
try
|
||||
{
|
||||
if (EmitMethodType == EmitHelper.EmitMethodType.HasResultTask && EmitDelegate is Func<object, object[], Task<object>> hasResultTask)
|
||||
{
|
||||
result = await hasResultTask(instance, args);
|
||||
}
|
||||
else if (EmitMethodType == EmitHelper.EmitMethodType.Task && EmitDelegate is Func<object, object[], Task> task)
|
||||
{
|
||||
await task.Invoke(instance, args);
|
||||
result = null;
|
||||
}
|
||||
else if (EmitMethodType == EmitHelper.EmitMethodType.Func && EmitDelegate is Func<object, object[], object> func)
|
||||
{
|
||||
result = func.Invoke(instance, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
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];
|
||||
@@ -173,26 +188,10 @@ namespace Serein.Library.Web
|
||||
|
||||
}
|
||||
|
||||
object result;
|
||||
object result = null;
|
||||
try
|
||||
{
|
||||
if (EmitMethodType == EmitHelper.EmitMethodType.HasResultTask && EmitDelegate is Func<object, object[], Task<object>> hasResultTask)
|
||||
{
|
||||
result = await hasResultTask(instance, args);
|
||||
}
|
||||
else if (EmitMethodType == EmitHelper.EmitMethodType.Task && EmitDelegate is Func<object, object[], Task> task)
|
||||
{
|
||||
await task.Invoke(instance, args);
|
||||
result = null;
|
||||
}
|
||||
else if (EmitMethodType == EmitHelper.EmitMethodType.Func && EmitDelegate is Func<object, object[], object> func)
|
||||
{
|
||||
result = func.Invoke(instance, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
result = await delegateDetails.InvokeAsync(instance, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -567,107 +566,6 @@ namespace Serein.Library.Web
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal static class WebFunc
|
||||
{
|
||||
public static bool ToBool(this JToken token, bool defult = false)
|
||||
{
|
||||
var value = token?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
if (!bool.TryParse(value, out bool result))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static int ToInt(this JToken token, int defult = 0)
|
||||
{
|
||||
var value = token?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
if (!int.TryParse(value, out int result))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static double ToDouble(this JToken token, double defult = 0)
|
||||
{
|
||||
var value = token?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
if (!int.TryParse(value, out int result))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region 已经注释
|
||||
|
||||
// private readonly ConcurrentDictionary<string, bool> _controllerAutoHosting; // 存储是否实例化
|
||||
// private readonly ConcurrentDictionary<string, object> _controllerInstances;
|
||||
|
||||
//public void CollectRoutes(Type controllerType)
|
||||
//{
|
||||
// string controllerName = controllerType.Name.Replace("Controller", "").ToLower(); // 获取控制器名称并转换为小写
|
||||
// foreach (var method in controllerType.GetMethods()) // 遍历控制器类型的所有方法
|
||||
// {
|
||||
// var routeAttribute = method.GetCustomAttribute<WebApiAttribute>(); // 获取方法上的 WebAPIAttribute 自定义属性
|
||||
// if (routeAttribute != null) // 如果存在 WebAPIAttribute 属性
|
||||
// {
|
||||
// var customUrl = routeAttribute.Url; // 获取自定义 URL
|
||||
// string url;
|
||||
// if (string.IsNullOrEmpty(customUrl)) // 如果自定义 URL 为空
|
||||
// {
|
||||
// url = $"/api/{controllerName}/{method.Name}".ToLower(); // 构建默认 URL
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// customUrl = CleanUrl(customUrl);
|
||||
// url = $"/api/{controllerName}/{method.Name}/{customUrl}".ToLower();// 清理自定义 URL,并构建新的 URL
|
||||
// }
|
||||
// var httpMethod = routeAttribute.Http; // 获取 HTTP 方法
|
||||
// _routes[httpMethod.ToString()].TryAdd(url, method); // 将 URL 和方法添加到对应的路由字典中
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//public void RegisterRoute<T>(T controllerInstance) // 方法声明,用于动态注册路由
|
||||
//{
|
||||
// Type controllerType = controllerInstance.GetType(); // 获取控制器实例的类型
|
||||
// var autoHostingAttribute = controllerType.GetCustomAttribute<AutoHostingAttribute>();
|
||||
// foreach (var method in controllerType.GetMethods()) // 遍历控制器类型的所有方法
|
||||
// {
|
||||
// var webAttribute = method.GetCustomAttribute<WebApiAttribute>(); // 获取方法上的 WebAPIAttribute 自定义属性
|
||||
// if (webAttribute != null) // 如果存在 WebAPIAttribute 属性
|
||||
// {
|
||||
// var url = AddRoutesUrl(autoHostingAttribute, webAttribute, controllerType, method);
|
||||
// if (url == null) continue;
|
||||
// _controllerInstances[url] = controllerInstance;
|
||||
// _controllerAutoHosting[url] = false;
|
||||
// }
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
64
Library/Network/Http/SereinExtension.cs
Normal file
64
Library/Network/Http/SereinExtension.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.Library.Network.Http
|
||||
{
|
||||
internal static partial class SereinExtension
|
||||
{
|
||||
#region JSON相关
|
||||
|
||||
public static bool ToBool(this JToken token, bool defult = false)
|
||||
{
|
||||
var value = token?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
if (!bool.TryParse(value, out bool result))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static int ToInt(this JToken token, int defult = 0)
|
||||
{
|
||||
var value = token?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
if (!int.TryParse(value, out int result))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static double ToDouble(this JToken token, double defult = 0)
|
||||
{
|
||||
var value = token?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
if (!int.TryParse(value, out int result))
|
||||
{
|
||||
return defult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
Action<Exception, Action<object>> onExceptionTracking,
|
||||
bool ArgNotNull)
|
||||
{
|
||||
EmitMethodType = EmitHelper.CreateDynamicMethod(methodInfo,out EmitDelegate);
|
||||
DelegateDetails = new DelegateDetails(methodInfo);
|
||||
this.Module = model;
|
||||
Instance = instance;
|
||||
var parameterInfos = methodInfo.GetParameters();
|
||||
@@ -72,15 +72,10 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
/// 参数不能为空
|
||||
/// </summary>
|
||||
private bool ArgNotNull;
|
||||
|
||||
/// <summary>
|
||||
/// Emit委托
|
||||
/// </summary>
|
||||
private readonly Delegate EmitDelegate;
|
||||
/// <summary>
|
||||
/// Emit委托类型
|
||||
/// </summary>
|
||||
private readonly EmitHelper.EmitMethodType EmitMethodType;
|
||||
private readonly DelegateDetails DelegateDetails;
|
||||
/// <summary>
|
||||
/// 未捕获的异常跟踪
|
||||
/// </summary>
|
||||
@@ -114,29 +109,26 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
/// </summary>
|
||||
private readonly bool[] IsCheckArgNotNull;
|
||||
|
||||
//private object ConvertArg(Type type, string argName )
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
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 DATA JSON数据
|
||||
if (useData[i])
|
||||
{
|
||||
args[i] = jsonObject.ToObject(type);
|
||||
}
|
||||
#endregion
|
||||
else if (useMsgId[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)
|
||||
{
|
||||
@@ -229,23 +221,7 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
object result;
|
||||
try
|
||||
{
|
||||
if (EmitMethodType == EmitHelper.EmitMethodType.HasResultTask && EmitDelegate is Func<object, object[], Task<object>> hasResultTask)
|
||||
{
|
||||
result = await hasResultTask(Instance, args);
|
||||
}
|
||||
else if (EmitMethodType == EmitHelper.EmitMethodType.Task && EmitDelegate is Func<object, object[], Task> task)
|
||||
{
|
||||
await task.Invoke(Instance, args);
|
||||
result = null;
|
||||
}
|
||||
else if (EmitMethodType == EmitHelper.EmitMethodType.Func && EmitDelegate is Func<object, object[], object> func)
|
||||
{
|
||||
result = func.Invoke(Instance, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
result = await DelegateDetails.InvokeAsync(Instance, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -256,25 +232,11 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
await SendAsync.Invoke(exData);
|
||||
}));
|
||||
}
|
||||
//sw.Stop();
|
||||
//Console.WriteLine($"Emit Invoke:{sw.ElapsedTicks * 1000000F / Stopwatch.Frequency:n3}μs");
|
||||
|
||||
|
||||
|
||||
if (Module.IsReturnValue)
|
||||
{
|
||||
if (result is null)
|
||||
{
|
||||
result = "null";
|
||||
}
|
||||
_ = SendAsync.Invoke(result);
|
||||
}
|
||||
//if( && result != null && result.GetType().IsClass)
|
||||
//{
|
||||
// //var reusltJsonText = JsonConvert.SerializeObject(result);
|
||||
|
||||
// //_ = SendAsync.Invoke($"{reusltJsonText}");
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
MyHandleConfigs.Clear();
|
||||
}
|
||||
|
||||
private HashSet<string> _myMsgIdHash = new HashSet<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 处理JSON数据
|
||||
/// </summary>
|
||||
@@ -106,11 +108,15 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
return;
|
||||
}
|
||||
string msgId = jsonObject.GetValue(MsgIdJsonKey)?.ToString();
|
||||
|
||||
if (_myMsgIdHash.Contains(msgId))
|
||||
{
|
||||
Console.WriteLine($"[{msgId}]{theme} 消息重复");
|
||||
return;
|
||||
}
|
||||
_myMsgIdHash.Add(msgId);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
JObject dataObj = jsonObject.GetValue(DataJsonKey)?.ToObject<JObject>();
|
||||
handldConfig.Handle(async (data) =>
|
||||
{
|
||||
@@ -170,9 +176,8 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
}
|
||||
|
||||
var msg = jsonData.ToString();
|
||||
//Console.WriteLine(msg);
|
||||
//Console.WriteLine();
|
||||
|
||||
|
||||
|
||||
await sendAsync.Invoke(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,21 +155,16 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
|
||||
/// <summary>
|
||||
/// 异步处理消息
|
||||
/// </summary>
|
||||
/// <param name="SendAsync"></param>
|
||||
/// <param name="sendAsync"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task HandleMsgAsync(Func<string, Task> SendAsync, string message)
|
||||
public void HandleMsg(Func<string, Task> sendAsync, string message)
|
||||
{
|
||||
//Console.WriteLine(message);
|
||||
JObject json = JObject.Parse(message);
|
||||
await Task.Run(() =>
|
||||
foreach (var module in MyHandleModuleDict.Values)
|
||||
{
|
||||
foreach (var module in MyHandleModuleDict.Values)
|
||||
{
|
||||
module.HandleSocketMsg(SendAsync, json);
|
||||
|
||||
}
|
||||
});
|
||||
module.HandleSocketMsg(sendAsync, json);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,28 +8,4 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
}
|
||||
|
||||
|
||||
//[AutoRegister(RegisterSequence.FlowLoading)]
|
||||
//[AutoSocketModule(JsonThemeField = "theme", JsonDataField = "data")]
|
||||
//public class UserService : ISocketControlBase
|
||||
//{
|
||||
// public Guid HandleGuid { get; } = new Guid();
|
||||
|
||||
// // Action<string> 类型是特殊的,会用一个委托代替,这个委托可以将文本信息发送到客户端
|
||||
// // Action<object> 类型是特殊的,会用一个委托代替,这个委托可以将对象转成json发送到客户端
|
||||
|
||||
// [AutoSocketHandle]
|
||||
// public void AddUser(User user,Action<string> Recover)
|
||||
// {
|
||||
// Console.WriteLine(user.ToString());
|
||||
// Recover("ok");
|
||||
// }
|
||||
|
||||
// [AutoSocketHandle(ThemeValue = "Remote")]
|
||||
// public void DeleteUser(User user, Action<string> Recover)
|
||||
// {
|
||||
// Console.WriteLine(user.ToString());
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
73
Library/Network/WebSocket/TestExtension.cs
Normal file
73
Library/Network/WebSocket/TestExtension.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using Serein.Library.Utils;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Serein.Library.Network.WebSocketCommunication
|
||||
{
|
||||
public class MsgQueueUtil
|
||||
{
|
||||
public ConcurrentQueue<string> Msgs = new ConcurrentQueue<string>();
|
||||
|
||||
private readonly Channel<string> _msgChannel;
|
||||
public MsgQueueUtil()
|
||||
{
|
||||
_msgChannel = CreateChannel();
|
||||
}
|
||||
|
||||
private Channel<string> CreateChannel()
|
||||
{
|
||||
return Channel.CreateBounded<string>(new BoundedChannelOptions(100)
|
||||
{
|
||||
FullMode = BoundedChannelFullMode.Wait
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待消息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<string> WaitMsgAsync()
|
||||
{
|
||||
var state = await _msgChannel.Reader.ReadAsync();
|
||||
return state;
|
||||
}
|
||||
|
||||
public void WriteMsg(string msg)
|
||||
{
|
||||
//Msgs.Enqueue(msg);
|
||||
Console.WriteLine($"{DateTime.Now}{msg}{Environment.NewLine}");
|
||||
_ = _msgChannel.Writer.WriteAsync(msg);
|
||||
}
|
||||
|
||||
public bool TryGetMsg(out string msg)
|
||||
{
|
||||
return Msgs.TryDequeue(out msg);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class SocketExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="webSocket"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task SendAsync(WebSocket webSocket, string message)
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
using Serein.Library.Network.WebSocketCommunication.Handle;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace Serein.Library.Network.WebSocketCommunication
|
||||
{
|
||||
@@ -38,7 +41,6 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
await _client.ConnectAsync(new Uri(uri), CancellationToken.None);
|
||||
_ = ReceiveAsync();
|
||||
return true;
|
||||
@@ -58,8 +60,12 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
/// <returns></returns>
|
||||
public async Task SendAsync(string message)
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await _client.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
Console.WriteLine("发送消息");
|
||||
await Task.Delay(2000);
|
||||
await SocketExtension.SendAsync(this._client, message); // 回复客户端
|
||||
Console.WriteLine();
|
||||
//var buffer = Encoding.UTF8.GetBytes(message);
|
||||
//await _client.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,13 +74,21 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
/// <returns></returns>
|
||||
private async Task ReceiveAsync()
|
||||
{
|
||||
var buffer = new byte[1024];
|
||||
|
||||
var msgQueueUtil = new MsgQueueUtil();
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await HandleMsgAsync(_client, msgQueueUtil);
|
||||
});
|
||||
|
||||
|
||||
var receivedMessage = new StringBuilder(); // 用于拼接长消息
|
||||
|
||||
while (_client.State == WebSocketState.Open)
|
||||
{
|
||||
try
|
||||
{
|
||||
var buffer = new byte[1024];
|
||||
WebSocketReceiveResult result;
|
||||
|
||||
do
|
||||
@@ -86,21 +100,22 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
receivedMessage.Append(partialMessage);
|
||||
|
||||
} while (!result.EndOfMessage); // 判断是否已经收到完整消息
|
||||
|
||||
var message = receivedMessage.ToString();
|
||||
msgQueueUtil.WriteMsg(message);
|
||||
receivedMessage.Clear(); // 清空 StringBuilder 为下一条消息做准备
|
||||
// 处理收到的完整消息
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
await _client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
var completeMessage = receivedMessage.ToString();
|
||||
_ = MsgHandleHelper.HandleMsgAsync(SendAsync, completeMessage); // 处理消息
|
||||
//Debug.WriteLine($"Received: {completeMessage}");
|
||||
}
|
||||
|
||||
// 清空 StringBuilder 为下一条消息做准备
|
||||
receivedMessage.Clear();
|
||||
//else
|
||||
//{
|
||||
// var completeMessage = receivedMessage.ToString();
|
||||
// MsgHandleHelper.HandleMsg(SendAsync, completeMessage); // 处理消息,如果方法入参是需要发送消息委托时,将 SendAsync 作为委托参数提供
|
||||
// //Debug.WriteLine($"Received: {completeMessage}");
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -110,65 +125,86 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
}
|
||||
|
||||
|
||||
/* #region 消息处理
|
||||
private readonly string ThemeField;
|
||||
private readonly ConcurrentDictionary<string, HandldConfig> ThemeConfigs = new ConcurrentDictionary<string, HandldConfig>();
|
||||
|
||||
public async Task HandleSocketMsg(string jsonStr)
|
||||
public async Task HandleMsgAsync(WebSocket webSocket,
|
||||
MsgQueueUtil msgQueueUtil)
|
||||
{
|
||||
JObject json;
|
||||
try
|
||||
{
|
||||
json = JObject.Parse(jsonStr);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await SendAsync(_client, ex.Message);
|
||||
return;
|
||||
}
|
||||
// 获取到消息
|
||||
string themeName = json[ThemeField]?.ToString();
|
||||
if (!ThemeConfigs.TryGetValue(themeName, out var handldConfig))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
object dataValue;
|
||||
if (string.IsNullOrEmpty(handldConfig.DataField))
|
||||
while (true)
|
||||
{
|
||||
dataValue = json.ToObject(handldConfig.DataType);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataValue = json[handldConfig.DataField].ToObject(handldConfig.DataType);
|
||||
}
|
||||
await handldConfig.Invoke(dataValue, SendAsync);
|
||||
}
|
||||
|
||||
public void AddConfig(string themeName, Type dataType, MsgHandler msgHandler)
|
||||
{
|
||||
if (!ThemeConfigs.TryGetValue(themeName, out var handldConfig))
|
||||
{
|
||||
handldConfig = new HandldConfig
|
||||
var message = await msgQueueUtil.WaitMsgAsync(); // 有消息时通知
|
||||
//if (!msgQueueUtil.TryGetMsg(out var message)) // 获取消息
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
// 消息处理
|
||||
MsgHandleHelper.HandleMsg(async (text) =>
|
||||
{
|
||||
DataField = themeName,
|
||||
DataType = dataType
|
||||
};
|
||||
ThemeConfigs.TryAdd(themeName, handldConfig);
|
||||
await SocketExtension.SendAsync(webSocket, text); // 回复客户端,处理方法中入参如果需要发送消息委托,则将该回调方法作为委托参数传入
|
||||
}, message); // 处理消息
|
||||
|
||||
}
|
||||
handldConfig.HandldAsync += msgHandler;
|
||||
}
|
||||
public void RemoteConfig(string themeName, MsgHandler msgHandler)
|
||||
{
|
||||
if (ThemeConfigs.TryGetValue(themeName, out var handldConfig))
|
||||
|
||||
|
||||
/* #region 消息处理
|
||||
private readonly string ThemeField;
|
||||
private readonly ConcurrentDictionary<string, HandldConfig> ThemeConfigs = new ConcurrentDictionary<string, HandldConfig>();
|
||||
|
||||
public async Task HandleSocketMsg(string jsonStr)
|
||||
{
|
||||
handldConfig.HandldAsync -= msgHandler;
|
||||
if (!handldConfig.HasSubscribers)
|
||||
JObject json;
|
||||
try
|
||||
{
|
||||
ThemeConfigs.TryRemove(themeName, out _);
|
||||
json = JObject.Parse(jsonStr);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await SendAsync(_client, ex.Message);
|
||||
return;
|
||||
}
|
||||
// 获取到消息
|
||||
string themeName = json[ThemeField]?.ToString();
|
||||
if (!ThemeConfigs.TryGetValue(themeName, out var handldConfig))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
object dataValue;
|
||||
if (string.IsNullOrEmpty(handldConfig.DataField))
|
||||
{
|
||||
dataValue = json.ToObject(handldConfig.DataType);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataValue = json[handldConfig.DataField].ToObject(handldConfig.DataType);
|
||||
}
|
||||
await handldConfig.Invoke(dataValue, SendAsync);
|
||||
}
|
||||
|
||||
public void AddConfig(string themeName, Type dataType, MsgHandler msgHandler)
|
||||
{
|
||||
if (!ThemeConfigs.TryGetValue(themeName, out var handldConfig))
|
||||
{
|
||||
handldConfig = new HandldConfig
|
||||
{
|
||||
DataField = themeName,
|
||||
DataType = dataType
|
||||
};
|
||||
ThemeConfigs.TryAdd(themeName, handldConfig);
|
||||
}
|
||||
handldConfig.HandldAsync += msgHandler;
|
||||
}
|
||||
public void RemoteConfig(string themeName, MsgHandler msgHandler)
|
||||
{
|
||||
if (ThemeConfigs.TryGetValue(themeName, out var handldConfig))
|
||||
{
|
||||
handldConfig.HandldAsync -= msgHandler;
|
||||
if (!handldConfig.HasSubscribers)
|
||||
{
|
||||
ThemeConfigs.TryRemove(themeName, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion*/
|
||||
}
|
||||
#endregion*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,67 +180,46 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
return;
|
||||
}
|
||||
|
||||
var msgQueueUtil = new MsgQueueUtil();
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await HandleMsgAsync(webSocket,msgQueueUtil, authorizedHelper);
|
||||
});
|
||||
|
||||
//Func<string, Task> SendAsync = async (text) =>
|
||||
//{
|
||||
// await WebSocketServer.SendAsync(webSocket, text);
|
||||
//};
|
||||
|
||||
var buffer = new byte[1024];
|
||||
var receivedMessage = new StringBuilder(); // 用于拼接长消息
|
||||
|
||||
while (webSocket.State == WebSocketState.Open)
|
||||
while ( webSocket.State == WebSocketState.Open)
|
||||
{
|
||||
WebSocketReceiveResult result;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
WebSocketReceiveResult result;
|
||||
var buffer = new byte[1024];
|
||||
do
|
||||
{
|
||||
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
if (IsCheckToken)
|
||||
{
|
||||
AuthorizedClients.TryRemove(authorizedHelper.AddresPort, out var _);
|
||||
}
|
||||
}
|
||||
// 将接收到的部分消息解码并拼接
|
||||
var partialMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);
|
||||
receivedMessage.Append(partialMessage);
|
||||
|
||||
} while (!result.EndOfMessage); // 循环直到接收到完整的消息
|
||||
|
||||
// 完整消息已经接收到,准备处理
|
||||
var message = receivedMessage.ToString();
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
//SendAsync = null;
|
||||
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
if (IsCheckToken)
|
||||
{
|
||||
AuthorizedClients.TryRemove(authorizedHelper.AddresPort, out var _);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsCheckToken)
|
||||
{
|
||||
var authorizedResult = await authorizedHelper.HandleAuthorized(message); // 尝试检测授权
|
||||
if (!authorizedResult) // 授权失败
|
||||
{
|
||||
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
if (IsCheckToken)
|
||||
{
|
||||
AuthorizedClients.TryRemove(authorizedHelper.AddresPort, out var _);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 消息处理
|
||||
_ = MsgHandleHelper.HandleMsgAsync(async (text) =>
|
||||
{
|
||||
await WebSocketServer.SendAsync(webSocket, text);
|
||||
}, message); // 处理消息
|
||||
}
|
||||
|
||||
// 清空 StringBuilder 为下一条消息做准备
|
||||
receivedMessage.Clear();
|
||||
var message = receivedMessage.ToString(); // 获取消息文本
|
||||
receivedMessage.Clear(); // 清空 StringBuilder 为下一条消息做准备
|
||||
msgQueueUtil.WriteMsg(message); // 处理消息
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -249,17 +228,45 @@ namespace Serein.Library.Network.WebSocketCommunication
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="webSocket"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task SendAsync(WebSocket webSocket, string message)
|
||||
|
||||
|
||||
public async Task HandleMsgAsync(WebSocket webSocket,
|
||||
MsgQueueUtil msgQueueUtil,
|
||||
WebSocketAuthorizedHelper authorizedHelper)
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
|
||||
while (true)
|
||||
{
|
||||
var message = await msgQueueUtil.WaitMsgAsync(); // 有消息时通知
|
||||
//if (!msgQueueUtil.TryGetMsg(out var message)) // 获取消息
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
if (IsCheckToken)
|
||||
{
|
||||
var authorizedResult = await authorizedHelper.HandleAuthorized(message); // 尝试检测授权
|
||||
if (!authorizedResult) // 授权失败
|
||||
{
|
||||
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
if (IsCheckToken)
|
||||
{
|
||||
AuthorizedClients.TryRemove(authorizedHelper.AddresPort, out var _);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 消息处理
|
||||
MsgHandleHelper.HandleMsg(async (text) =>
|
||||
{
|
||||
await SocketExtension.SendAsync(webSocket, text); // 回复客户端,处理方法中入参如果需要发送消息委托,则将该回调方法作为委托参数传入
|
||||
}, message); // 处理消息
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>1.0.17</Version>
|
||||
<Version>1.0.18</Version>
|
||||
<TargetFrameworks>net8.0;net462</TargetFrameworks>
|
||||
<!--<TargetFrameworks>net8.0</TargetFrameworks>-->
|
||||
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
|
||||
@@ -37,7 +37,6 @@
|
||||
<ItemGroup>
|
||||
|
||||
<ProjectReference Include="..\Serein.Library.MyGenerator\Serein.Library.NodeGenerator.csproj" OutputItemType="Analyzer" />
|
||||
<!--ReferenceOutputAssembly="false"-->
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
||||
|
||||
@@ -100,4 +100,14 @@ namespace Serein.Library.Utils
|
||||
return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded<(TriggerType, object)>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Serein.Library.Utils
|
||||
/// <summary>
|
||||
/// 管理远程环境,具备连接、发送消息、停止的功能
|
||||
/// </summary>
|
||||
public class RemoteEnvControl
|
||||
public class RemoteMsgUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 远程环境配置
|
||||
@@ -52,7 +52,7 @@ namespace Serein.Library.Utils
|
||||
/// <summary>
|
||||
/// 配置远程连接IP端口
|
||||
/// </summary>
|
||||
public RemoteEnvControl(ControlConfiguration controlConfiguration)
|
||||
public RemoteMsgUtil(ControlConfiguration controlConfiguration)
|
||||
{
|
||||
Config = controlConfiguration;
|
||||
}
|
||||
@@ -120,13 +120,6 @@ namespace Serein.Library.Utils
|
||||
/// <returns></returns>
|
||||
public async Task SendAsync(string msgId , string theme, object data)
|
||||
{
|
||||
//var sendMsg = new
|
||||
//{
|
||||
// theme = theme,
|
||||
// token = this.Token,
|
||||
// data = data,
|
||||
//};
|
||||
//var msg = JsonConvert.SerializeObject(sendMsg);
|
||||
JObject jsonData;
|
||||
|
||||
if (data is null)
|
||||
@@ -156,11 +149,8 @@ namespace Serein.Library.Utils
|
||||
[Config.DataJsonKey] = dataToken
|
||||
};
|
||||
}
|
||||
|
||||
var msg = jsonData.ToString();
|
||||
//Console.WriteLine(msg);
|
||||
//Console.WriteLine();
|
||||
|
||||
Console.WriteLine($"[{msgId}] => {theme}");
|
||||
await EnvClient.SendAsync(msg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user