2016-01-30 update 3
This commit is contained in:
161
Modbus.Net/Modbus.Net(temp)/BaseProtocal.cs
Normal file
161
Modbus.Net/Modbus.Net(temp)/BaseProtocal.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 基本协议
|
||||
/// </summary>
|
||||
public abstract class BaseProtocal
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议的连接器
|
||||
/// </summary>
|
||||
public ProtocalLinker ProtocalLinker { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造器
|
||||
/// </summary>
|
||||
protected BaseProtocal()
|
||||
{
|
||||
Protocals = new Dictionary<string, ProtocalUnit>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议
|
||||
/// </summary>
|
||||
/// <param name="type">协议的类的GetType</param>
|
||||
/// <returns>协议的实例</returns>
|
||||
public ProtocalUnit this[Type type]
|
||||
{
|
||||
get
|
||||
{
|
||||
string protocalName = type.FullName;
|
||||
if (Protocals.ContainsKey(protocalName))
|
||||
{
|
||||
return Protocals[protocalName];
|
||||
}
|
||||
//自动寻找存在的协议并将其加载
|
||||
var protocalUnit =
|
||||
Assembly.Load(type.Assembly.FullName).CreateInstance(protocalName) as ProtocalUnit;
|
||||
if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容");
|
||||
Register(protocalUnit);
|
||||
return Protocals[protocalName];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 协议集合
|
||||
/// </summary>
|
||||
protected Dictionary<string, ProtocalUnit> Protocals { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册一个协议
|
||||
/// </summary>
|
||||
/// <param name="linkProtocal">需要注册的协议</param>
|
||||
protected void Register(ProtocalUnit linkProtocal)
|
||||
{
|
||||
if (linkProtocal == null) return;
|
||||
Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
/// <param name="content">写入的内容,使用对象数组描述</param>
|
||||
/// <returns>从设备获取的字节流</returns>
|
||||
public virtual byte[] SendReceive(params object[] content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议内容并接收,一般方法
|
||||
/// </summary>
|
||||
/// <param name="content">写入的内容,使用对象数组描述</param>
|
||||
/// <returns>从设备获取的字节流</returns>
|
||||
public virtual async Task<byte[]> SendReceiveAsync(params object[] content)
|
||||
{
|
||||
if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
|
||||
{
|
||||
await ConnectAsync();
|
||||
}
|
||||
if (ProtocalLinker != null)
|
||||
{
|
||||
return await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(content));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的实例</param>
|
||||
/// <param name="content">输入信息的结构化描述</param>
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
|
||||
{
|
||||
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送协议,通过传入需要使用的协议内容和输入结构
|
||||
/// </summary>
|
||||
/// <param name="unit">协议的实例</param>
|
||||
/// <param name="content">输入信息的结构化描述</param>
|
||||
/// <returns>输出信息的结构化描述</returns>
|
||||
public virtual async Task<OutputStruct> SendReceiveAsync(ProtocalUnit unit, InputStruct content)
|
||||
{
|
||||
int t = 0;
|
||||
var formatContent = unit.Format(content);
|
||||
if (formatContent != null)
|
||||
{
|
||||
byte[] receiveContent;
|
||||
//如果为特别处理协议的话,跳过协议扩展收缩
|
||||
if (unit is SpecialProtocalUnit)
|
||||
{
|
||||
receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent);
|
||||
}
|
||||
if (receiveContent != null)
|
||||
{
|
||||
return unit.Unformat(receiveContent, ref t);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user