This commit is contained in:
parallelbgls
2017-05-24 09:41:09 +08:00
13 changed files with 182 additions and 89 deletions

View File

@@ -65,7 +65,8 @@
/// <summary>
/// 读数据协议
/// </summary>
public class ReadRequestOpcProtocal : ProtocalUnit<OpcParamIn, OpcParamOut>, ISpecialProtocalUnit
[SpecialProtocalUnit]
public class ReadRequestOpcProtocal : ProtocalUnit<OpcParamIn, OpcParamOut>
{
/// <summary>
/// 从对象的参数数组格式化
@@ -156,7 +157,8 @@
/// <summary>
/// 写数据协议
/// </summary>
public class WriteRequestOpcProtocal : ProtocalUnit<OpcParamIn, OpcParamOut>, ISpecialProtocalUnit
[SpecialProtocalUnit]
public class WriteRequestOpcProtocal : ProtocalUnit<OpcParamIn, OpcParamOut>
{
/// <summary>
/// 从对象的参数数组格式化

View File

@@ -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
/// <summary>
/// 串口消息确认协议
/// </summary>
public class ComConfirmMessageSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
[SpecialProtocalUnit]
public class ComConfirmMessageSiemensProtocal : ProtocalUnit
{
/// <summary>
/// 格式化

View File

@@ -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
{
...
}

View File

@@ -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
/// 基本协议
/// </summary>
public abstract class BaseProtocal<TParamIn, TParamOut, TProtocalUnit> :
IProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
IProtocal<TParamIn, TParamOut, TProtocalUnit> where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut>
where TParamOut : class
{
/// <summary>
/// 构造器
@@ -66,9 +68,9 @@ namespace Modbus.Net
public byte MasterAddress { get; set; }
/// <summary>
/// 协议的连接器
/// 协议集合
/// </summary>
public ProtocalLinker<TParamIn, TParamOut> ProtocalLinker { get; protected set; }
protected Dictionary<string, TProtocalUnit> Protocals { get; }
/// <summary>
/// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
@@ -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];
}
}
/// <summary>
/// 协议集合
/// 协议的连接器
/// </summary>
protected Dictionary<string, TProtocalUnit> Protocals { get; }
public IProtocalLinker<TParamIn, TParamOut> ProtocalLinker { get; protected set; }
/// <summary>
/// 协议连接开始
/// </summary>
/// <returns></returns>
public abstract bool Connect();
/// <summary>
/// 协议连接开始(异步)
/// </summary>
/// <returns></returns>
public abstract Task<bool> ConnectAsync();
/// <summary>
/// 协议连接断开
/// </summary>
/// <returns></returns>
public virtual bool Disconnect()
{
if (ProtocalLinker != null)
return ProtocalLinker.Disconnect();
return false;
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -132,31 +159,21 @@ namespace Modbus.Net
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
public virtual byte[] SendReceive(params object[] content)
public virtual TParamOut SendReceive(params object[] content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
}
/// <summary>
/// 发送协议内容并接收,一般方法
/// 发送协议内容并接收,一般方法(不能使用,如需使用请继承)
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
public virtual Task<byte[]> SendReceiveAsync(params object[] content)
public virtual Task<TParamOut> SendReceiveAsync(params object[] content)
{
throw new NotImplementedException();
}
/// <summary>
/// 注册一个协议
/// </summary>
/// <param name="linkProtocal">需要注册的协议</param>
protected void Register(TProtocalUnit linkProtocal)
{
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
@@ -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
}
/// <summary>
/// 协议连接开始
/// 注册一个协议
/// </summary>
/// <returns></returns>
public abstract bool Connect();
/// <summary>
/// 协议连接开始(异步)
/// </summary>
/// <returns></returns>
public abstract Task<bool> ConnectAsync();
/// <summary>
/// 协议连接断开
/// </summary>
/// <returns></returns>
public virtual bool Disconnect()
/// <param name="linkProtocal">需要注册的协议</param>
protected void Register(TProtocalUnit linkProtocal)
{
if (ProtocalLinker != null)
return ProtocalLinker.Disconnect();
return false;
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
}
}
}

View File

@@ -44,12 +44,12 @@ namespace Modbus.Net
/// 基础Api入口
/// </summary>
public abstract class BaseUtility<TParamIn, TParamOut, TProtocalUnit> : IUtilityProperty, IUtilityMethodData
where TProtocalUnit : ProtocalUnit<TParamIn, TParamOut>
where TProtocalUnit : class, IProtocalFormatting<TParamIn, TParamOut> where TParamOut : class
{
/// <summary>
/// 协议收发主体
/// </summary>
protected BaseProtocal<TParamIn, TParamOut, TProtocalUnit> Wrapper;
protected IProtocal<TParamIn, TParamOut, TProtocalUnit> Wrapper;
/// <summary>
/// 构造器

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
namespace Modbus.Net
{
@@ -8,22 +9,52 @@ namespace Modbus.Net
/// <typeparam name="TParamIn">向Connector传入的类型</typeparam>
/// <typeparam name="TParamOut">从Connector返回的类型</typeparam>
/// <typeparam name="TProtocalUnit">协议单元的类型</typeparam>
public interface IProtocal<TParamIn, TParamOut, in TProtocalUnit>
public interface IProtocal<TParamIn, TParamOut, TProtocalUnit>
where TProtocalUnit : IProtocalFormatting<TParamIn, TParamOut>
{
/// <summary>
/// 发送协议内容并接收,一般方法
/// 协议的连接器
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
byte[] SendReceive(params object[] content);
IProtocalLinker<TParamIn, TParamOut> ProtocalLinker { get; }
/// <summary>
/// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
/// </summary>
/// <param name="type">协议的类的GetType</param>
/// <returns>协议的实例</returns>
TProtocalUnit this[Type type] { get; }
/// <summary>
/// 协议连接开始
/// </summary>
/// <returns></returns>
bool Connect();
/// <summary>
/// 协议连接开始(异步)
/// </summary>
/// <returns></returns>
Task<bool> ConnectAsync();
/// <summary>
/// 协议连接断开
/// </summary>
/// <returns></returns>
bool Disconnect();
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
Task<byte[]> SendReceiveAsync(params object[] content);
TParamOut SendReceive(params object[] content);
/// <summary>
/// 发送协议内容并接收,一般方法
/// </summary>
/// <param name="content">写入的内容,使用对象数组描述</param>
/// <returns>从设备获取的字节流</returns>
Task<TParamOut> SendReceiveAsync(params object[] content);
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
@@ -40,5 +71,23 @@ namespace Modbus.Net
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
Task<IOutputStruct> SendReceiveAsync(TProtocalUnit unit, IInputStruct content);
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
T SendReceive<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct;
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
/// <param name="unit">协议的实例</param>
/// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns>
/// <typeparam name="T">IOutputStruct的具体类型</typeparam>
Task<T> SendReceiveAsync<T>(TProtocalUnit unit, IInputStruct content) where T : class, IOutputStruct;
}
}

View File

@@ -14,6 +14,11 @@
/// <typeparam name="TParamOut">从Connector返回的数据类型</typeparam>
public interface IProtocalFormatting<out TParamIn, in TParamOut>
{
/// <summary>
/// 是否为小端格式
/// </summary>
Endian Endian { get; set; }
/// <summary>
/// 从输入结构格式化
/// </summary>

View File

@@ -9,6 +9,34 @@ namespace Modbus.Net
/// <typeparam name="TParamOut">从Connector返回的数据类型</typeparam>
public interface IProtocalLinker<TParamIn, TParamOut>
{
/// <summary>
/// 通讯字符串
/// </summary>
string ConnectionToken { get; }
/// <summary>
/// 设备是否连接
/// </summary>
bool IsConnected { get; }
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
bool Connect();
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
Task<bool> ConnectAsync();
/// <summary>
/// 断开设备
/// </summary>
/// <returns>设备是否断开成功</returns>
bool Disconnect();
/// <summary>
/// 发送并接收数据
/// </summary>

View File

@@ -71,12 +71,40 @@ namespace Modbus.Net
/// 基本的协议连接器
/// </summary>
public abstract class ProtocalLinker<TParamIn, TParamOut> : IProtocalLinker<TParamIn, TParamOut>
where TParamOut : class
{
/// <summary>
/// 传输连接器
/// </summary>
protected BaseConnector<TParamIn, TParamOut> BaseConnector;
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public bool Connect()
{
return BaseConnector.Connect();
}
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public async Task<bool> ConnectAsync()
{
return await BaseConnector.ConnectAsync();
}
/// <summary>
/// 断开设备
/// </summary>
/// <returns>设备是否断开成功</returns>
public bool Disconnect()
{
return BaseConnector.Disconnect();
}
/// <summary>
/// 通讯字符串
/// </summary>
@@ -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);
}
/// <summary>
@@ -132,8 +159,7 @@ namespace Modbus.Net
//容错处理
var checkRight = CheckRight(receiveBytes);
//返回字符
if (checkRight == true) return receiveBytes;
throw new NullReferenceException();
return checkRight == true ? receiveBytes : null;
}
/// <summary>
@@ -167,32 +193,5 @@ namespace Modbus.Net
{
throw new NotImplementedException();
}
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public bool Connect()
{
return BaseConnector.Connect();
}
/// <summary>
/// 连接设备
/// </summary>
/// <returns>设备是否连接成功</returns>
public async Task<bool> ConnectAsync()
{
return await BaseConnector.ConnectAsync();
}
/// <summary>
/// 断开设备
/// </summary>
/// <returns>设备是否断开成功</returns>
public bool Disconnect()
{
return BaseConnector.Disconnect();
}
}
}

View File

@@ -71,7 +71,8 @@ namespace Modbus.Net
/// <summary>
/// 特殊协议单元写入这个协议不会执行BytesExtend和BytesDecact
/// </summary>
public interface ISpecialProtocalUnit
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class SpecialProtocalUnitAttribute : Attribute
{
}

View File

@@ -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)

View File

@@ -87,7 +87,7 @@ namespace AnyType.Controllers
{
Console.WriteLine($"ip {returnValues.MachineId} not return value");
}
}, 15000, 60000));
}, MachineGetDataType.CommunicationTag, 15000, 60000));
}
[HttpGet]

View File

@@ -79,7 +79,7 @@ namespace TaskManager.Controllers
{
Console.WriteLine($"ip {returnValues.MachineId} not return value");
}
}, 15000, 60000));
}, MachineGetDataType.CommunicationTag, 15000, 60000));
}
[HttpGet]