2017-07-31 Update 1 Add Pipeline

This commit is contained in:
parallelbgls
2017-07-31 17:24:45 +08:00
parent d5bc2881c9
commit 76719986f6
13 changed files with 219 additions and 88 deletions

View File

@@ -5,7 +5,7 @@
<AssemblyName>Modbus.Net.Core</AssemblyName> <AssemblyName>Modbus.Net.Core</AssemblyName>
<RootNamespace>Modbus.Net</RootNamespace> <RootNamespace>Modbus.Net</RootNamespace>
<PackageId>Modbus.Net.Core</PackageId> <PackageId>Modbus.Net.Core</PackageId>
<Version>1.3.9</Version> <Version>1.4.0</Version>
<Product>Modbus.Net</Product> <Product>Modbus.Net</Product>
<Authors>Chris L.(Luo Sheng)</Authors> <Authors>Chris L.(Luo Sheng)</Authors>
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company> <Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
@@ -52,6 +52,7 @@
<Compile Include="..\src\Base.Common\IMachineMethod.cs" Link="IMachineMethod.cs" /> <Compile Include="..\src\Base.Common\IMachineMethod.cs" Link="IMachineMethod.cs" />
<Compile Include="..\src\Base.Common\TypeExtensions.cs" Link="TypeExtensions.cs" /> <Compile Include="..\src\Base.Common\TypeExtensions.cs" Link="TypeExtensions.cs" />
<Compile Include="..\src\Base.Common\IConnector.cs" Link="IConnector.cs" /> <Compile Include="..\src\Base.Common\IConnector.cs" Link="IConnector.cs" />
<Compile Include="..\src\Base.Common\PipeUnit.cs" Link="PipeUnit.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -5,7 +5,7 @@
<AssemblyName>Modbus.Net.Modbus</AssemblyName> <AssemblyName>Modbus.Net.Modbus</AssemblyName>
<RootNamespace>Modbus.Net.Modbus</RootNamespace> <RootNamespace>Modbus.Net.Modbus</RootNamespace>
<PackageId>Modbus.Net.Modbus</PackageId> <PackageId>Modbus.Net.Modbus</PackageId>
<Version>1.3.9</Version> <Version>1.4.0</Version>
<Authors>Chris L.(Luo Sheng)</Authors> <Authors>Chris L.(Luo Sheng)</Authors>
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company> <Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
<Product>Modbus.Net.Modbus</Product> <Product>Modbus.Net.Modbus</Product>

View File

@@ -5,7 +5,7 @@
<AssemblyName>Modbus.Net.OPC</AssemblyName> <AssemblyName>Modbus.Net.OPC</AssemblyName>
<RootNamespace>Modbus.Net.OPC</RootNamespace> <RootNamespace>Modbus.Net.OPC</RootNamespace>
<PackageId>Modbus.Net.OPC</PackageId> <PackageId>Modbus.Net.OPC</PackageId>
<Version>1.3.9</Version> <Version>1.4.0</Version>
<Authors>Chris L.(Luo Sheng)</Authors> <Authors>Chris L.(Luo Sheng)</Authors>
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company> <Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
<Description>Modbus.Net OPC Implementation</Description> <Description>Modbus.Net OPC Implementation</Description>

View File

@@ -3,7 +3,9 @@
/// <summary> /// <summary>
/// Opc协议 /// Opc协议
/// </summary> /// </summary>
public abstract class OpcProtocal : BaseProtocal<OpcParamIn, OpcParamOut, ProtocalUnit<OpcParamIn, OpcParamOut>> public abstract class OpcProtocal : BaseProtocal<OpcParamIn, OpcParamOut, ProtocalUnit<OpcParamIn, OpcParamOut>,
PipeUnit<OpcParamIn, OpcParamOut, IProtocalLinker<OpcParamIn, OpcParamOut>,
ProtocalUnit<OpcParamIn, OpcParamOut>>>
{ {
/// <summary> /// <summary>
/// 构造函数 /// 构造函数

View File

@@ -7,7 +7,9 @@ namespace Modbus.Net.OPC
/// <summary> /// <summary>
/// Opc通用Api入口 /// Opc通用Api入口
/// </summary> /// </summary>
public abstract class OpcUtility : BaseUtility<OpcParamIn, OpcParamOut, ProtocalUnit<OpcParamIn, OpcParamOut>> public abstract class OpcUtility : BaseUtility<OpcParamIn, OpcParamOut, ProtocalUnit<OpcParamIn, OpcParamOut>,
PipeUnit<OpcParamIn, OpcParamOut, IProtocalLinker<OpcParamIn, OpcParamOut>,
ProtocalUnit<OpcParamIn, OpcParamOut>>>
{ {
/// <summary> /// <summary>
/// 获取分隔符 /// 获取分隔符
@@ -80,7 +82,8 @@ namespace Modbus.Net.OPC
try try
{ {
var split = GetSeperator?.Invoke() ?? '/'; var split = GetSeperator?.Invoke() ?? '/';
var writeRequestOpcInputStruct = new WriteRequestOpcInputStruct(startAddress.Split('\r'), split, setContents[0]); var writeRequestOpcInputStruct =
new WriteRequestOpcInputStruct(startAddress.Split('\r'), split, setContents[0]);
var writeRequestOpcOutputStruct = var writeRequestOpcOutputStruct =
await await
Wrapper.SendReceiveAsync<WriteRequestOpcOutputStruct>(Wrapper[typeof(WriteRequestOpcProtocal)], Wrapper.SendReceiveAsync<WriteRequestOpcOutputStruct>(Wrapper[typeof(WriteRequestOpcProtocal)],

View File

@@ -5,7 +5,7 @@
<AssemblyName>Modbus.Net.Siemens</AssemblyName> <AssemblyName>Modbus.Net.Siemens</AssemblyName>
<RootNamespace>Modbus.Net.Siemens</RootNamespace> <RootNamespace>Modbus.Net.Siemens</RootNamespace>
<PackageId>Modbus.Net.Siemens</PackageId> <PackageId>Modbus.Net.Siemens</PackageId>
<Version>1.3.9</Version> <Version>1.4.0</Version>
<Authors>Chris L.(Luo Sheng)</Authors> <Authors>Chris L.(Luo Sheng)</Authors>
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company> <Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
<Description>Modbus.Net Siemens Profinet Implementation</Description> <Description>Modbus.Net Siemens Profinet Implementation</Description>

View File

@@ -37,7 +37,7 @@ namespace Modbus.Net.Siemens
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
public override byte[] SendReceive(params object[] content) public override PipeUnit SendReceive(params object[] content)
{ {
return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content)); return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content));
} }
@@ -47,7 +47,7 @@ namespace Modbus.Net.Siemens
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
public override async Task<byte[]> SendReceiveAsync(params object[] content) public override async Task<PipeUnit> SendReceiveAsync(params object[] content)
{ {
if (ProtocalLinker == null || !ProtocalLinker.IsConnected) if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
await ConnectAsync(); await ConnectAsync();
@@ -60,7 +60,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">协议核心</param> /// <param name="unit">协议核心</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>设备返回的信息</returns> /// <returns>设备返回的信息</returns>
private async Task<IOutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content) private async Task<PipeUnit> ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{ {
return await base.SendReceiveAsync(unit, content); return await base.SendReceiveAsync(unit, content);
} }
@@ -83,21 +83,14 @@ namespace Modbus.Net.Siemens
ProtocalLinker = new SiemensPpiProtocalLinker(_com, SlaveAddress); ProtocalLinker = new SiemensPpiProtocalLinker(_com, SlaveAddress);
var inputStruct = new ComCreateReferenceSiemensInputStruct(SlaveAddress, MasterAddress); var inputStruct = new ComCreateReferenceSiemensInputStruct(SlaveAddress, MasterAddress);
var outputStruct = var outputStruct =
await await (await (await
ForceSendReceiveAsync(this[typeof(ComCreateReferenceSiemensProtocal)], ForceSendReceiveAsync(this[typeof(ComCreateReferenceSiemensProtocal)],
inputStruct). inputStruct)).
ContinueWith(async answer => SendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocal)], answer =>
{
if (!ProtocalLinker.IsConnected) return false; new ComConfirmMessageSiemensInputStruct(SlaveAddress, MasterAddress)
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(SlaveAddress, MasterAddress); )).Unwrap<ComConfirmMessageSiemensOutputStruct>();
var outputStruct2 = return outputStruct != null;
(ComConfirmMessageSiemensOutputStruct)
await
ForceSendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocal)],
inputStruct2);
return outputStruct2 != null;
});
return outputStruct;
} }
} }
} }

View File

@@ -81,7 +81,7 @@ namespace Modbus.Net.Siemens
/// </summary> /// </summary>
/// <param name="content">发送的数据</param> /// <param name="content">发送的数据</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
public override byte[] SendReceive(params object[] content) public override PipeUnit SendReceive(params object[] content)
{ {
return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content)); return AsyncHelper.RunSync(() => SendReceiveAsync(Endian, content));
} }
@@ -91,7 +91,7 @@ namespace Modbus.Net.Siemens
/// </summary> /// </summary>
/// <param name="content">发送的数据</param> /// <param name="content">发送的数据</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
public override async Task<byte[]> SendReceiveAsync(params object[] content) public override async Task<PipeUnit> SendReceiveAsync(params object[] content)
{ {
if (ProtocalLinker == null || !ProtocalLinker.IsConnected) if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
await ConnectAsync(); await ConnectAsync();
@@ -104,7 +104,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">协议的核心</param> /// <param name="unit">协议的核心</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
public override IOutputStruct SendReceive(ProtocalUnit unit, IInputStruct content) public override PipeUnit SendReceive(ProtocalUnit unit, IInputStruct content)
{ {
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content)); return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
} }
@@ -115,15 +115,14 @@ namespace Modbus.Net.Siemens
/// <param name="unit">发送的数据</param> /// <param name="unit">发送的数据</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
public override async Task<IOutputStruct> SendReceiveAsync(ProtocalUnit unit, IInputStruct content) public override async Task<PipeUnit> SendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{ {
if (ProtocalLinker != null && ProtocalLinker.IsConnected) return await base.SendReceiveAsync(unit, content); if (ProtocalLinker != null && ProtocalLinker.IsConnected) return await base.SendReceiveAsync(unit, content);
if (_connectTryCount > 10) return null; if (_connectTryCount > 10) return null;
return return
await await
await ConnectAsync()
ConnectAsync() .ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null).Unwrap();
.ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null);
} }
/// <summary> /// <summary>
@@ -132,7 +131,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">发送的数据</param> /// <param name="unit">发送的数据</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
private async Task<IOutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content) private async Task<PipeUnit> ForceSendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{ {
return await base.SendReceiveAsync(unit, content); return await base.SendReceiveAsync(unit, content);
} }
@@ -157,23 +156,15 @@ namespace Modbus.Net.Siemens
if (!await ProtocalLinker.ConnectAsync()) return false; if (!await ProtocalLinker.ConnectAsync()) return false;
_connectTryCount = 0; _connectTryCount = 0;
var inputStruct = new CreateReferenceSiemensInputStruct(_tdpuSize, _taspSrc, _tsapDst); var inputStruct = new CreateReferenceSiemensInputStruct(_tdpuSize, _taspSrc, _tsapDst);
return var outputStruct =
//先建立连接,然后建立设备的引用 //先建立连接,然后建立设备的引用
await await (await (await
ForceSendReceiveAsync(this[typeof(CreateReferenceSiemensProtocal)], inputStruct) ForceSendReceiveAsync(this[typeof(CreateReferenceSiemensProtocal)], inputStruct)).SendReceiveAsync(
.ContinueWith(async answer => this[typeof(EstablishAssociationSiemensProtocal)], answer =>
{ new EstablishAssociationSiemensInputStruct(0x0101, _maxCalling,
if (!ProtocalLinker.IsConnected) return false; _maxCalled,
var inputStruct2 = new EstablishAssociationSiemensInputStruct(0x0101, _maxCalling, _maxPdu))).Unwrap<EstablishAssociationSiemensOutputStruct>();
_maxCalled, return outputStruct != null;
_maxPdu);
var outputStruct2 =
(EstablishAssociationSiemensOutputStruct)
await
SendReceiveAsync(this[typeof(EstablishAssociationSiemensProtocal)],
inputStruct2);
return outputStruct2 != null;
});
} }
} }
} }

View File

@@ -5,7 +5,7 @@
<AssemblyName>Modbus.Net</AssemblyName> <AssemblyName>Modbus.Net</AssemblyName>
<RootNamespace>Modbus.Net</RootNamespace> <RootNamespace>Modbus.Net</RootNamespace>
<PackageId>Modbus.Net</PackageId> <PackageId>Modbus.Net</PackageId>
<Version>1.3.9</Version> <Version>1.4.0</Version>
<Product>Modbus.Net</Product> <Product>Modbus.Net</Product>
<Authors>Chris L.(Luo Sheng)</Authors> <Authors>Chris L.(Luo Sheng)</Authors>
<Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company> <Company>Hangzhou Delian IoT Science Technology Co.,Ltd.</Company>
@@ -52,6 +52,7 @@
<Compile Include="..\src\Base.Common\IMachineMethod.cs" Link="IMachineMethod.cs" /> <Compile Include="..\src\Base.Common\IMachineMethod.cs" Link="IMachineMethod.cs" />
<Compile Include="..\src\Base.Common\TypeExtensions.cs" Link="TypeExtensions.cs" /> <Compile Include="..\src\Base.Common\TypeExtensions.cs" Link="TypeExtensions.cs" />
<Compile Include="..\src\Base.Common\IConnector.cs" Link="IConnector.cs" /> <Compile Include="..\src\Base.Common\IConnector.cs" Link="IConnector.cs" />
<Compile Include="..\src\Base.Common\PipeUnit.cs" Link="PipeUnit.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -9,7 +9,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 基本协议 /// 基本协议
/// </summary> /// </summary>
public abstract class BaseProtocal : BaseProtocal<byte[], byte[], ProtocalUnit> public abstract class BaseProtocal : BaseProtocal<byte[], byte[], ProtocalUnit, PipeUnit>
{ {
/// <summary> /// <summary>
/// 构造器 /// 构造器
@@ -24,12 +24,32 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
public override async Task<byte[]> SendReceiveAsync(params object[] content) public override async Task<PipeUnit> SendReceiveAsync(params object[] content)
{ {
if (ProtocalLinker == null || !ProtocalLinker.IsConnected) if (content != null)
await ConnectAsync(); {
if (ProtocalLinker != null) var pipeUnit =
return await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(Endian, content)); new PipeUnit(
ProtocalLinker);
return await pipeUnit.SendReceiveAsync(Endian, paramOut => content);
}
return null;
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
public override async Task<PipeUnit>
SendReceiveAsync(ProtocalUnit unit, IInputStruct content)
{
if (content != null)
{
var pipeUnit = new PipeUnit(ProtocalLinker);
return await pipeUnit.SendReceiveAsync(unit, paramOut => content);
}
return null; return null;
} }
} }
@@ -37,9 +57,11 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 基本协议 /// 基本协议
/// </summary> /// </summary>
public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit> : public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit, TPipeUnit> :
IProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut> IProtocal<TParamIn, TParamOut, TProtocalUnit, TPipeUnit>
where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut>
where TParamOut : class where TParamOut : class
where TPipeUnit : PipeUnit<TParamIn, TParamOut, IProtocalLinker<TParamIn, TParamOut>, TProtocalUnit>
{ {
/// <summary> /// <summary>
/// 构造器 /// 构造器
@@ -93,7 +115,8 @@ namespace Modbus.Net
{ {
//自动寻找存在的协议并将其加载 //自动寻找存在的协议并将其加载
var protocalUnit = var protocalUnit =
Activator.CreateInstance(type.GetTypeInfo().Assembly.GetType(protocalName)) as TProtocalUnit; Activator.CreateInstance(type.GetTypeInfo().Assembly
.GetType(protocalName)) as TProtocalUnit;
if (protocalUnit == null) if (protocalUnit == null)
throw new InvalidCastException($"No ProtocalUnit {nameof(TProtocalUnit)} implemented"); throw new InvalidCastException($"No ProtocalUnit {nameof(TProtocalUnit)} implemented");
protocalUnit.Endian = Endian; protocalUnit.Endian = Endian;
@@ -138,7 +161,8 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param> /// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
public virtual IOutputStruct SendReceive(TProtocalUnit unit, IInputStruct content) public virtual TPipeUnit SendReceive(
TProtocalUnit unit, IInputStruct content)
{ {
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content)); return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
} }
@@ -149,9 +173,17 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param> /// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
public virtual async Task<IOutputStruct> SendReceiveAsync(TProtocalUnit unit, IInputStruct content) public virtual async Task<TPipeUnit>
SendReceiveAsync(TProtocalUnit unit, IInputStruct content)
{ {
return await SendReceiveAsync<IOutputStruct>(unit, content); if (content != null)
{
var pipeUnit =
new PipeUnit<TParamIn, TParamOut, IProtocalLinker<TParamIn, TParamOut>, TProtocalUnit>(
ProtocalLinker);
return await pipeUnit.SendReceiveAsync(unit, paramOut => content) as TPipeUnit;
}
return null;
} }
/// <summary> /// <summary>
@@ -159,7 +191,7 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
public virtual TParamOut SendReceive(params object[] content) public virtual TPipeUnit SendReceive(params object[] content)
{ {
return AsyncHelper.RunSync(() => SendReceiveAsync(content)); return AsyncHelper.RunSync(() => SendReceiveAsync(content));
} }
@@ -169,7 +201,7 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
public virtual Task<TParamOut> SendReceiveAsync(params object[] content) public virtual Task<TPipeUnit> SendReceiveAsync(params object[] content)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@@ -196,20 +228,7 @@ namespace Modbus.Net
public virtual async Task<T> SendReceiveAsync<T>(TProtocalUnit unit, IInputStruct content) public virtual async Task<T> SendReceiveAsync<T>(TProtocalUnit unit, IInputStruct content)
where T : class, IOutputStruct where T : class, IOutputStruct
{ {
var t = 0; return (await SendReceiveAsync(unit, content)).Unwrap<T>();
var formatContent = unit.Format(content);
if (formatContent != null)
{
TParamOut receiveContent;
//如果为特别处理协议的话,跳过协议扩展收缩
if (unit.GetType().GetTypeInfo().GetCustomAttributes(typeof(SpecialProtocalUnitAttribute)).Any())
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
else
receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent);
if (receiveContent != null)
return unit.Unformat<T>(receiveContent, ref t);
}
return null;
} }
/// <summary> /// <summary>

View File

@@ -30,7 +30,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 基础Api入口 /// 基础Api入口
/// </summary> /// </summary>
public abstract class BaseUtility : BaseUtility<byte[], byte[], ProtocalUnit> public abstract class BaseUtility : BaseUtility<byte[], byte[], ProtocalUnit, PipeUnit>
{ {
/// <summary> /// <summary>
/// 构造器 /// 构造器
@@ -43,13 +43,14 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 基础Api入口 /// 基础Api入口
/// </summary> /// </summary>
public abstract class BaseUtility<TParamIn, TParamOut, TProtocalUnit> : IUtilityProperty, IUtilityMethodData public abstract class BaseUtility<TParamIn, TParamOut, TProtocalUnit, TPipeUnit> : IUtilityProperty, IUtilityMethodData
where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut> where TParamOut : class where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut> where TParamOut : class
where TPipeUnit : PipeUnit<TParamIn, TParamOut, IProtocalLinker<TParamIn, TParamOut>, TProtocalUnit>
{ {
/// <summary> /// <summary>
/// 协议收发主体 /// 协议收发主体
/// </summary> /// </summary>
protected IProtocal<TParamIn, TParamOut, TProtocalUnit> Wrapper; protected IProtocal<TParamIn, TParamOut, TProtocalUnit, TPipeUnit> Wrapper;
/// <summary> /// <summary>
/// 构造器 /// 构造器

View File

@@ -9,8 +9,10 @@ namespace Modbus.Net
/// <typeparam name="TParamIn">向Connector传入的类型</typeparam> /// <typeparam name="TParamIn">向Connector传入的类型</typeparam>
/// <typeparam name="TParamOut">从Connector返回的类型</typeparam> /// <typeparam name="TParamOut">从Connector返回的类型</typeparam>
/// <typeparam name="TProtocalUnit">协议单元的类型</typeparam> /// <typeparam name="TProtocalUnit">协议单元的类型</typeparam>
public interface IProtocal<TParamIn, TParamOut, TProtocalUnit> public interface IProtocal<TParamIn, TParamOut, TProtocalUnit, TPipeUnit>
where TProtocalUnit : IProtocalFormatting<TParamIn, TParamOut> where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut>
where TParamOut : class
where TPipeUnit : PipeUnit<TParamIn, TParamOut, IProtocalLinker<TParamIn, TParamOut>, TProtocalUnit>
{ {
/// <summary> /// <summary>
/// 协议的连接器 /// 协议的连接器
@@ -47,14 +49,14 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
TParamOut SendReceive(params object[] content); TPipeUnit SendReceive(params object[] content);
/// <summary> /// <summary>
/// 发送协议内容并接收,一般方法 /// 发送协议内容并接收,一般方法
/// </summary> /// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param> /// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns> /// <returns>从设备获取的字节流</returns>
Task<TParamOut> SendReceiveAsync(params object[] content); Task<TPipeUnit> SendReceiveAsync(params object[] content);
/// <summary> /// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构 /// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -62,7 +64,7 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param> /// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
IOutputStruct SendReceive(TProtocalUnit unit, IInputStruct content); TPipeUnit SendReceive(TProtocalUnit unit, IInputStruct content);
/// <summary> /// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构 /// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -70,7 +72,7 @@ namespace Modbus.Net
/// <param name="unit">协议的实例</param> /// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
Task<IOutputStruct> SendReceiveAsync(TProtocalUnit unit, IInputStruct content); Task<TPipeUnit> SendReceiveAsync(TProtocalUnit unit, IInputStruct content);
/// <summary> /// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构 /// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -79,7 +81,8 @@ namespace Modbus.Net
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam> /// <typeparam name="T">IOutputStruct的具体类型</typeparam>
T SendReceive<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct; T SendReceive<T>(
TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct;
/// <summary> /// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构 /// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -88,6 +91,7 @@ namespace Modbus.Net
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam> /// <typeparam name="T">IOutputStruct的具体类型</typeparam>
Task<T> SendReceiveAsync<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct; Task<T> SendReceiveAsync<T>(
TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct;
} }
} }

View File

@@ -0,0 +1,116 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace Modbus.Net
{
public class PipeUnit : PipeUnit<byte[], byte[], IProtocalLinker<byte[], byte[]>, ProtocalUnit>
{
public PipeUnit(IProtocalLinker<byte[], byte[]> protocalLinker) : base(protocalLinker)
{
}
protected PipeUnit(IProtocalLinker<byte[], byte[]> protocalLinker, ProtocalUnit protocalUnit, byte[] parameters,
bool success) : base(protocalLinker, protocalUnit, parameters, success)
{
}
public async Task<PipeUnit> SendReceiveAsync(Endian endian, Func<byte[], object[]> inputStructCreator)
{
if (Success)
{
var content = inputStructCreator.Invoke(ReturnParams);
if (ProtocalLinker != null)
return new PipeUnit(ProtocalLinker, null,
await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(endian, content)),
true);
}
return new PipeUnit(ProtocalLinker, null, ReturnParams, false);
}
public async Task<PipeUnit> SendReceiveAsync(
ProtocalUnit unit,
Func<byte[], IInputStruct> inputStructCreator)
{
var receiveContent = await SendReceiveAsync1(unit, inputStructCreator);
if (receiveContent != null)
return new PipeUnit(ProtocalLinker, unit,
receiveContent, true);
return new PipeUnit(ProtocalLinker, unit, ReturnParams,
false);
}
public byte[] Unwrap()
{
return ReturnParams;
}
}
public class PipeUnit<TParamIn, TParamOut, TProtocalLinker, TProtocalUnit>
where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut>
where TProtocalLinker : class, IProtocalLinker<TParamIn, TParamOut>
where TParamOut : class
{
public PipeUnit(TProtocalLinker protocalLinker) : this(protocalLinker, null, null, true)
{
}
protected PipeUnit(TProtocalLinker protocalLinker, TProtocalUnit protocalUnit, TParamOut parameters, bool success)
{
ProtocalLinker = protocalLinker;
ProtocalUnit = protocalUnit;
ReturnParams = parameters;
Success = success;
}
protected TProtocalLinker ProtocalLinker { get; set; }
protected TProtocalUnit ProtocalUnit { get; set; }
protected TParamOut ReturnParams { get; set; }
public bool Success { get; }
protected async Task<TParamOut> SendReceiveAsync1(TProtocalUnit unit,
Func<TParamOut, IInputStruct> inputStructCreator)
{
if (Success)
{
var content = inputStructCreator.Invoke(ReturnParams);
var formatContent = unit.Format(content);
if (formatContent != null)
{
TParamOut receiveContent;
//如果为特别处理协议的话,跳过协议扩展收缩
if (unit.GetType().GetTypeInfo().GetCustomAttributes(typeof(SpecialProtocalUnitAttribute)).Any())
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
else
receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent);
return receiveContent;
}
}
return null;
}
public virtual async Task<PipeUnit<TParamIn, TParamOut, TProtocalLinker, TProtocalUnit>> SendReceiveAsync(
TProtocalUnit unit,
Func<TParamOut, IInputStruct> inputStructCreator)
{
var receiveContent = await SendReceiveAsync1(unit, inputStructCreator);
if (receiveContent != null)
return new PipeUnit<TParamIn, TParamOut, TProtocalLinker, TProtocalUnit>(ProtocalLinker, unit,
receiveContent, true);
return new PipeUnit<TParamIn, TParamOut, TProtocalLinker, TProtocalUnit>(ProtocalLinker, unit, ReturnParams,
false);
}
public T Unwrap<T>() where T : class, IOutputStruct
{
var t = 0;
return ProtocalUnit.Unformat<T>(ReturnParams, ref t);
}
}
}