diff --git a/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs b/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs
index ca56811..0b7d66a 100644
--- a/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs
+++ b/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs
@@ -65,7 +65,8 @@
///
/// 读数据协议
///
- public class ReadRequestOpcProtocal : ProtocalUnit, ISpecialProtocalUnit
+ [SpecialProtocalUnit]
+ public class ReadRequestOpcProtocal : ProtocalUnit
{
///
/// 从对象的参数数组格式化
@@ -156,7 +157,8 @@
///
/// 写数据协议
///
- public class WriteRequestOpcProtocal : ProtocalUnit, ISpecialProtocalUnit
+ [SpecialProtocalUnit]
+ public class WriteRequestOpcProtocal : ProtocalUnit
{
///
/// 从对象的参数数组格式化
diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs
index 5a08905..d40729f 100644
--- a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs
+++ b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs
@@ -146,7 +146,8 @@ namespace Modbus.Net.Siemens
public byte ConfirmMessage { get; set; }
}
- internal class ComCreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
+ [SpecialProtocalUnit]
+ internal class ComCreateReferenceSiemensProtocal : ProtocalUnit
{
public override byte[] Format(IInputStruct message)
{
@@ -200,7 +201,8 @@ namespace Modbus.Net.Siemens
public ushort TsapDst { get; }
}
- internal class CreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
+ [SpecialProtocalUnit]
+ internal class CreateReferenceSiemensProtocal : ProtocalUnit
{
public override byte[] Format(IInputStruct message)
{
@@ -306,7 +308,8 @@ namespace Modbus.Net.Siemens
///
/// 串口消息确认协议
///
- public class ComConfirmMessageSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
+ [SpecialProtocalUnit]
+ public class ComConfirmMessageSiemensProtocal : ProtocalUnit
{
///
/// 格式化
diff --git a/Modbus.Net/Modbus.Net/README.md b/Modbus.Net/Modbus.Net/README.md
index f096d6d..b0b2ddd 100644
--- a/Modbus.Net/Modbus.Net/README.md
+++ b/Modbus.Net/Modbus.Net/README.md
@@ -394,10 +394,11 @@ public class ReadDataModbusProtocal : ProtocalUnit
}
}
```
-There is another interface called ISpecialProtocalUnit.
-If you add ISpecialProtocalUnit to ProtocalUnit, then the protocal will not run BytesExtend and BytesDecact.
+There is another attribute called SpecialProtocalUnitAttribute.
+If you add SpecialProtocalUnitAttribute to ProtocalUnit, then the protocal will not run BytesExtend and BytesDecact.
```C#
-internal class CreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
+[SpecialProtocalUnit]
+internal class CreateReferenceSiemensProtocal : ProtocalUnit
{
...
}
diff --git a/Modbus.Net/src/Base.Common/BaseProtocal.cs b/Modbus.Net/src/Base.Common/BaseProtocal.cs
index c31b6ce..0f7acfb 100644
--- a/Modbus.Net/src/Base.Common/BaseProtocal.cs
+++ b/Modbus.Net/src/Base.Common/BaseProtocal.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
@@ -37,7 +38,8 @@ namespace Modbus.Net
/// 基本协议
///
public abstract class BaseProtocal :
- IProtocal where TProtocalUnit : ProtocalUnit
+ IProtocal where TProtocalUnit : class, IProtocalFormatting
+ where TParamOut : class
{
///
/// 构造器
@@ -66,9 +68,9 @@ namespace Modbus.Net
public byte MasterAddress { get; set; }
///
- /// 协议的连接器
+ /// 协议集合
///
- public ProtocalLinker ProtocalLinker { get; protected set; }
+ protected Dictionary Protocals { get; }
///
/// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
@@ -84,7 +86,9 @@ namespace Modbus.Net
lock (Protocals)
{
if (Protocals.ContainsKey(protocalName))
+ {
protocalUnitReturn = Protocals[protocalName];
+ }
else
{
//自动寻找存在的协议并将其加载
@@ -94,16 +98,39 @@ namespace Modbus.Net
throw new InvalidCastException($"No ProtocalUnit {nameof(TProtocalUnit)} implemented");
protocalUnit.Endian = Endian;
Register(protocalUnit);
- }
+ }
}
return protocalUnitReturn ?? Protocals[protocalName];
}
}
///
- /// 协议集合
+ /// 协议的连接器
///
- protected Dictionary Protocals { get; }
+ public IProtocalLinker ProtocalLinker { get; protected set; }
+
+ ///
+ /// 协议连接开始
+ ///
+ ///
+ public abstract bool Connect();
+
+ ///
+ /// 协议连接开始(异步)
+ ///
+ ///
+ public abstract Task ConnectAsync();
+
+ ///
+ /// 协议连接断开
+ ///
+ ///
+ public virtual bool Disconnect()
+ {
+ if (ProtocalLinker != null)
+ return ProtocalLinker.Disconnect();
+ return false;
+ }
///
/// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -132,31 +159,21 @@ namespace Modbus.Net
///
/// 写入的内容,使用对象数组描述
/// 从设备获取的字节流
- public virtual byte[] SendReceive(params object[] content)
+ public virtual TParamOut SendReceive(params object[] content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
}
///
- /// 发送协议内容并接收,一般方法
+ /// 发送协议内容并接收,一般方法(不能使用,如需使用请继承)
///
/// 写入的内容,使用对象数组描述
/// 从设备获取的字节流
- public virtual Task SendReceiveAsync(params object[] content)
+ public virtual Task SendReceiveAsync(params object[] content)
{
throw new NotImplementedException();
}
- ///
- /// 注册一个协议
- ///
- /// 需要注册的协议
- protected void Register(TProtocalUnit linkProtocal)
- {
- if (linkProtocal == null) return;
- Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
- }
-
///
/// 发送协议,通过传入需要使用的协议内容和输入结构
///
@@ -185,7 +202,7 @@ namespace Modbus.Net
{
TParamOut receiveContent;
//如果为特别处理协议的话,跳过协议扩展收缩
- if (unit is ISpecialProtocalUnit)
+ if (unit.GetType().GetTypeInfo().GetCustomAttributes(typeof(SpecialProtocalUnitAttribute)).Any())
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
else
receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent);
@@ -196,26 +213,13 @@ namespace Modbus.Net
}
///
- /// 协议连接开始
+ /// 注册一个协议
///
- ///
- public abstract bool Connect();
-
- ///
- /// 协议连接开始(异步)
- ///
- ///
- public abstract Task ConnectAsync();
-
- ///
- /// 协议连接断开
- ///
- ///
- public virtual bool Disconnect()
+ /// 需要注册的协议
+ protected void Register(TProtocalUnit linkProtocal)
{
- if (ProtocalLinker != null)
- return ProtocalLinker.Disconnect();
- return false;
+ if (linkProtocal == null) return;
+ Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
}
}
}
\ No newline at end of file
diff --git a/Modbus.Net/src/Base.Common/BaseUtility.cs b/Modbus.Net/src/Base.Common/BaseUtility.cs
index ddb7331..fb1cd9b 100644
--- a/Modbus.Net/src/Base.Common/BaseUtility.cs
+++ b/Modbus.Net/src/Base.Common/BaseUtility.cs
@@ -44,12 +44,12 @@ namespace Modbus.Net
/// 基础Api入口
///
public abstract class BaseUtility : IUtilityProperty, IUtilityMethodData
- where TProtocalUnit : ProtocalUnit
+ where TProtocalUnit : class, IProtocalFormatting where TParamOut : class
{
///
/// 协议收发主体
///
- protected BaseProtocal Wrapper;
+ protected IProtocal Wrapper;
///
/// 构造器
diff --git a/Modbus.Net/src/Base.Common/IProtocal.cs b/Modbus.Net/src/Base.Common/IProtocal.cs
index 2bb48bd..0739ee7 100644
--- a/Modbus.Net/src/Base.Common/IProtocal.cs
+++ b/Modbus.Net/src/Base.Common/IProtocal.cs
@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
namespace Modbus.Net
{
@@ -8,22 +9,52 @@ namespace Modbus.Net
/// 向Connector传入的类型
/// 从Connector返回的类型
/// 协议单元的类型
- public interface IProtocal
+ public interface IProtocal
where TProtocalUnit : IProtocalFormatting
{
///
- /// 发送协议内容并接收,一般方法
+ /// 协议的连接器
///
- /// 写入的内容,使用对象数组描述
- /// 从设备获取的字节流
- byte[] SendReceive(params object[] content);
+ IProtocalLinker ProtocalLinker { get; }
+
+ ///
+ /// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
+ ///
+ /// 协议的类的GetType
+ /// 协议的实例
+ TProtocalUnit this[Type type] { get; }
+
+ ///
+ /// 协议连接开始
+ ///
+ ///
+ bool Connect();
+
+ ///
+ /// 协议连接开始(异步)
+ ///
+ ///
+ Task ConnectAsync();
+
+ ///
+ /// 协议连接断开
+ ///
+ ///
+ bool Disconnect();
///
/// 发送协议内容并接收,一般方法
///
/// 写入的内容,使用对象数组描述
/// 从设备获取的字节流
- Task SendReceiveAsync(params object[] content);
+ TParamOut SendReceive(params object[] content);
+
+ ///
+ /// 发送协议内容并接收,一般方法
+ ///
+ /// 写入的内容,使用对象数组描述
+ /// 从设备获取的字节流
+ Task SendReceiveAsync(params object[] content);
///
/// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -40,5 +71,23 @@ namespace Modbus.Net
/// 输入信息的结构化描述
/// 输出信息的结构化描述
Task SendReceiveAsync(TProtocalUnit unit, IInputStruct content);
+
+ ///
+ /// 发送协议,通过传入需要使用的协议内容和输入结构
+ ///
+ /// 协议的实例
+ /// 输入信息的结构化描述
+ /// 输出信息的结构化描述
+ /// IOutputStruct的具体类型
+ T SendReceive(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct;
+
+ ///
+ /// 发送协议,通过传入需要使用的协议内容和输入结构
+ ///
+ /// 协议的实例
+ /// 输入信息的结构化描述
+ /// 输出信息的结构化描述
+ /// IOutputStruct的具体类型
+ Task SendReceiveAsync(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct;
}
}
\ No newline at end of file
diff --git a/Modbus.Net/src/Base.Common/IProtocalFormatting.cs b/Modbus.Net/src/Base.Common/IProtocalFormatting.cs
index b9ff233..d156e00 100644
--- a/Modbus.Net/src/Base.Common/IProtocalFormatting.cs
+++ b/Modbus.Net/src/Base.Common/IProtocalFormatting.cs
@@ -14,6 +14,11 @@
/// 从Connector返回的数据类型
public interface IProtocalFormatting
{
+ ///
+ /// 是否为小端格式
+ ///
+ Endian Endian { get; set; }
+
///
/// 从输入结构格式化
///
diff --git a/Modbus.Net/src/Base.Common/IProtocalLinker.cs b/Modbus.Net/src/Base.Common/IProtocalLinker.cs
index eb1091a..2dde9e8 100644
--- a/Modbus.Net/src/Base.Common/IProtocalLinker.cs
+++ b/Modbus.Net/src/Base.Common/IProtocalLinker.cs
@@ -9,6 +9,34 @@ namespace Modbus.Net
/// 从Connector返回的数据类型
public interface IProtocalLinker
{
+ ///
+ /// 通讯字符串
+ ///
+ string ConnectionToken { get; }
+
+ ///
+ /// 设备是否连接
+ ///
+ bool IsConnected { get; }
+
+ ///
+ /// 连接设备
+ ///
+ /// 设备是否连接成功
+ bool Connect();
+
+ ///
+ /// 连接设备
+ ///
+ /// 设备是否连接成功
+ Task ConnectAsync();
+
+ ///
+ /// 断开设备
+ ///
+ /// 设备是否断开成功
+ bool Disconnect();
+
///
/// 发送并接收数据
///
diff --git a/Modbus.Net/src/Base.Common/ProtocalLinker.cs b/Modbus.Net/src/Base.Common/ProtocalLinker.cs
index bd7accd..9c9716c 100644
--- a/Modbus.Net/src/Base.Common/ProtocalLinker.cs
+++ b/Modbus.Net/src/Base.Common/ProtocalLinker.cs
@@ -71,12 +71,40 @@ namespace Modbus.Net
/// 基本的协议连接器
///
public abstract class ProtocalLinker : IProtocalLinker
+ where TParamOut : class
{
///
/// 传输连接器
///
protected BaseConnector BaseConnector;
+ ///
+ /// 连接设备
+ ///
+ /// 设备是否连接成功
+ public bool Connect()
+ {
+ return BaseConnector.Connect();
+ }
+
+ ///
+ /// 连接设备
+ ///
+ /// 设备是否连接成功
+ public async Task ConnectAsync()
+ {
+ return await BaseConnector.ConnectAsync();
+ }
+
+ ///
+ /// 断开设备
+ ///
+ /// 设备是否断开成功
+ public bool Disconnect()
+ {
+ return BaseConnector.Disconnect();
+ }
+
///
/// 通讯字符串
///
@@ -106,8 +134,7 @@ namespace Modbus.Net
{
var extBytes = BytesExtend(content);
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
- if (receiveBytes != null) return receiveBytes;
- throw new NullReferenceException();
+ return BytesDecact(receiveBytes);
}
///
@@ -132,8 +159,7 @@ namespace Modbus.Net
//容错处理
var checkRight = CheckRight(receiveBytes);
//返回字符
- if (checkRight == true) return receiveBytes;
- throw new NullReferenceException();
+ return checkRight == true ? receiveBytes : null;
}
///
@@ -167,32 +193,5 @@ namespace Modbus.Net
{
throw new NotImplementedException();
}
-
- ///
- /// 连接设备
- ///
- /// 设备是否连接成功
- public bool Connect()
- {
- return BaseConnector.Connect();
- }
-
- ///
- /// 连接设备
- ///
- /// 设备是否连接成功
- public async Task ConnectAsync()
- {
- return await BaseConnector.ConnectAsync();
- }
-
- ///
- /// 断开设备
- ///
- /// 设备是否断开成功
- public bool Disconnect()
- {
- return BaseConnector.Disconnect();
- }
}
}
\ No newline at end of file
diff --git a/Modbus.Net/src/Base.Common/ProtocalUnit.cs b/Modbus.Net/src/Base.Common/ProtocalUnit.cs
index 5360a73..c3f308c 100644
--- a/Modbus.Net/src/Base.Common/ProtocalUnit.cs
+++ b/Modbus.Net/src/Base.Common/ProtocalUnit.cs
@@ -71,7 +71,8 @@ namespace Modbus.Net
///
/// 特殊协议单元,写入这个协议不会执行BytesExtend和BytesDecact
///
- public interface ISpecialProtocalUnit
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ public class SpecialProtocalUnitAttribute : Attribute
{
}
diff --git a/README.md b/README.md
index 4aacd09..1cf4274 100644
--- a/README.md
+++ b/README.md
@@ -80,6 +80,7 @@ Platform Supported
### Version 1.3.8
* Change Resx to app.config or appsettings.json, now you can set default params there (Not Tested)
+* Change ISpecialProtocalUnit to SpecialProtocalUnitAttribute
### Version 1.4.0
* New Protocal Pipeline System (In Road)
diff --git a/Samples/AnyType/Controllers/HomeController.cs b/Samples/AnyType/Controllers/HomeController.cs
index ad7d7de..3216039 100644
--- a/Samples/AnyType/Controllers/HomeController.cs
+++ b/Samples/AnyType/Controllers/HomeController.cs
@@ -87,7 +87,7 @@ namespace AnyType.Controllers
{
Console.WriteLine($"ip {returnValues.MachineId} not return value");
}
- }, 15000, 60000));
+ }, MachineGetDataType.CommunicationTag, 15000, 60000));
}
[HttpGet]
diff --git a/Samples/TaskManager/Controllers/HomeController.cs b/Samples/TaskManager/Controllers/HomeController.cs
index 484df23..a481007 100644
--- a/Samples/TaskManager/Controllers/HomeController.cs
+++ b/Samples/TaskManager/Controllers/HomeController.cs
@@ -79,7 +79,7 @@ namespace TaskManager.Controllers
{
Console.WriteLine($"ip {returnValues.MachineId} not return value");
}
- }, 15000, 60000));
+ }, MachineGetDataType.CommunicationTag, 15000, 60000));
}
[HttpGet]