1.C#跨平台物聯網通訊框架ServerSuperIO(SSIO)介紹
《連載 | 物聯網框架ServerSuperIO教程》1.4種通訊模式機制。
《連載 | 物聯網框架ServerSuperIO教程》2.服務實例的配置參數說明
定位ServerSuperIO(SSIO)為物聯網通訊框架,就是因為這個框架是以“設備”(驅動)為核心構建,“設備”是泛指傳感器、下位機、PC機等各類數據源,數據源有自己的通訊協議或數據傳輸格式;ServerSuperIO並不是以IO通道為核心構建的框架,但是ServerSuperIO有很好的通訊能力,完全可以部署在服務端,並且支持多個服務實例,以及可以在Linux下運行。
ServerSuperIO的“設備”統一接口定義為IRunDevice,這是在框架內部運行、調度、與IO通道協作的唯一接口。代碼定義如下:
public interface IRunDevice: IServerProvider,IVirtualDevice { #region 函數接口 /// <summary> /// 初始化設備,加載設備驅動的頭一件事就是初始化設備 /// </summary> /// <param name="devid"></param> void Initialize(string devid); /// <summary> /// 保存原始的byte數據 /// </summary> /// <param name="data"></param> void SaveBytes(byte[] data, string desc); /// <summary> /// 獲得發送數據的命令,如果命令緩存中沒有命令,則調用獲得實時數據函數 /// </summary> /// <returns></returns> byte[] GetSendBytes(); /// <summary> /// 如果當前命令緩存沒有命令,則調用該函數,一般返回獲得設備的實時數據命令, /// </summary> /// <returns></returns> byte[] GetConstantCommand(); /// <summary> /// 發送IO數據接口 /// </summary> /// <param name="io"></param> /// <param name="senddata"></param> int Send(IChannel io, byte[] senddata); /// <summary> /// 讀取IO數據接口 /// </summary> /// <param name="io"></param> /// <returns></returns> byte[] Receive(IChannel io); /// <summary> /// 接收數據信息,帶過濾器 /// </summary> /// <param name="io"></param> /// <param name="receiveFilter"></param> /// <returns></returns> IList<byte[]> Receive(IChannel io, IReceiveFilter receiveFilter); /// <summary> /// 同步運行設備(IO) /// </summary> /// <param name="io">io實例對象</param> void Run(IChannel io); /// <summary> /// 同步運行設備(byte[]) /// </summary> /// <param name="key"></param> /// <param name="channel"></param> /// <param name="revData">接收到的數據</param> void Run(string key, IChannel channel, IRequestInfo ri); /// <summary> /// 如果通訊正常,這個函數負責處理數據 /// </summary> /// <param name="info"></param> void Communicate(IRequestInfo info); /// <summary> /// 通訊中斷,未接收到數據 /// </summary> void CommunicateInterrupt(IRequestInfo info); /// <summary> /// 通訊的數據錯誤或受到干擾 /// </summary> void CommunicateError(IRequestInfo info); /// <summary> /// 通訊未知,默認狀態(一般不用) /// </summary> void CommunicateNone(); /// <summary> /// 檢測通訊狀態 /// </summary> /// <param name="revdata"></param> /// <returns></returns> CommunicateState CheckCommunicateState(byte[] revdata); /// <summary> /// 報警接口函數 /// </summary> void Alert(); /// <summary> /// 保存解析後的數據 /// </summary> void Save(); /// <summary> /// 展示 /// </summary> void Show(); /// <summary> /// 當通訊實例為NULL的時候,調用該函數 /// </summary> void UnknownIO(); /// <summary> /// 通訊狀態改變 /// </summary> /// <param name="comState">改變後的狀態</param> void CommunicateStateChanged(CommunicateState comState); /// <summary> /// 通道狀態改變 /// </summary> /// <param name="channelState"></param> void ChannelStateChanged(ChannelState channelState); /// <summary> /// 當軟件關閉的時間,響應設備退出操作 /// </summary> void Exit(); /// <summary> /// 刪除設備的響應接口函數 /// </summary> void Delete(); /// <summary> /// 可以自定義返數據對象,用於與其他組件交互 /// </summary> /// <returns></returns> object GetObject(); /// <summary> /// 設備定時器,響應定時任務 /// </summary> void OnRunTimer(); /// <summary> /// 顯示上下文菜單 /// </summary> void ShowContextMenu(); /// <summary> /// 顯示IO監視器的窗體 /// </summary> void ShowMonitorDialog(); /// <summary> /// 在IO監視器上顯示byte[]數據 /// </summary> /// <param name="data"></param> /// <param name="desc"></param> void ShowMonitorData(byte[] data, string desc); #endregion #region 屬性接口 /// <summary> /// 默認程序集ID,用於存儲臨時對象 /// </summary> object Tag { set; get; } /// <summary> /// 同步對象,用於IO互拆 /// </summary> object SyncLock { get; } /// <summary> /// 實時數據持久接口 /// </summary> IDeviceDynamic DeviceDynamic { get; } /// <summary> /// 設備參數持久接口 /// </summary> IDeviceParameter DeviceParameter { get; } /// <summary> /// 協議驅動 /// </summary> IProtocolDriver Protocol { get; } /// <summary> /// 是否開啟時鐘,標識是否調用OnRunTimer接口函數。 /// </summary> bool IsRunTimer { set; get;} /// <summary> /// 時鐘間隔值,標識定時調用DeviceTimer接口函數的周期 /// </summary> int RunTimerInterval { set; get; } /// <summary> /// 設備的類型 /// </summary> DeviceType DeviceType { get; } /// <summary> /// 設備編號 /// </summary> string ModelNumber { get;} /// <summary> /// 設備運行權限級別,如果運行級別高的話,則優先發送和接收數據。 /// </summary> DevicePriority DevicePriority { get;set;} /// <summary> /// 設備的通訊類型 /// </summary> CommunicateType CommunicateType { get;set;} /// <summary> /// 標識是否運行設備,如果為false,調用運行設備接口時直接返回 /// </summary> bool IsRunDevice{ get;set;} /// <summary> /// 是否釋放資源 /// </summary> bool IsDisposed { get; } /// <summary> /// 顯示視圖 /// </summary> Control DeviceGraphics { get;} #endregion #region 事件接口 /// <summary> /// 發送數據事件 /// </summary> event SendDataHandler SendData; /// <summary> /// 發送數據事件,對SendDataHandler事件的封裝 /// </summary> /// <param name="senddata"></param> void OnSendData(byte[] senddata); /// <summary> /// 設備日志輸出事件 /// </summary> event DeviceRuningLogHandler DeviceRuningLog; /// <summary> /// 運行監視器顯示日志事件,對DeviceRuningLogHandler事件的封裝 /// </summary> void OnDeviceRuningLog(string statetext); /// <summary> /// 串口參數改變事件 /// </summary> event ComParameterExchangeHandler ComParameterExchange; /// <summary> /// 串口參數改變事件,對COMParameterExchangeHandler事件的封裝 /// </summary> void OnComParameterExchange(int oldcom, int oldbaud, int newcom, int newbaud); /// <summary> /// 設備數據對象改變事件 /// </summary> event DeviceObjectChangedHandler DeviceObjectChanged; /// <summary> /// 數據驅動事件,對DeviceObjectChangedHandler事件的封裝 /// </summary> void OnDeviceObjectChanged(object obj); ///// <summary> ///// 刪除設備事件 ///// </summary> //event DeleteDeviceCompletedHandler DeleteDeviceCompleted; ///// <summary> ///// 刪除設備事件,對DeleteDeviceHandler事件的封裝 ///// </summary> //void OnDeleteDeviceCompleted(); #endregion }
RunDevice抽象類繼承自IRunDevice接口,本質上來講,二次開發只需要繼承RunDevice抽象類就可以了。RunDevice已經完成了設備驅動在ServerSuperIO框架下基本的條件。那麼在繼承RunDevice抽象類的時候,所需要二次開發的工作很小,只需要關注協議和處理數據業務本身,對於框架的內部運行機制可以配置、調度機制內部自動處理。
二次開發常用的接口,項目示意如下圖:
1.[連載]《C#通訊(串口和網絡)框架的設計與實現》