《連載 | 物聯網框架ServerSuperIO教程》- 12.服務介面的開發,以及與雲端雙向互動
目 錄
12.服務介面的開發,以及與雲端雙向互動... 2
12.1 概述... 2
12.2 裝置連結器... 2
12.3 服務連結器... 3
12.4 場景假設... 3
12.5 裝置驅動開發及注意事項... 4
12.6 服務例項開發及注意事項... 4
12.7 宿主程式服務例項配置注意事項... 8
12.8 執行效果... 9
12.服務介面的開發,以及與雲端雙向互動
12.1 概述
服務介面IService是除裝置驅動介面IRunDevice外的特殊應用場景,例如:簡訊報警、LED輸出、模擬量的採集、OPC服務端/客戶端、資料的級聯轉發、以及其他的特殊應用。是基於裝置驅動介面IRunDevice的有力擴充套件,讓框架的功能更豐富和強大。
這篇文章主要介紹資料的轉發和控制服務,其他的服務開發與此類似。如果基於ServerSuperIO服務介面的開發具備資料轉發和控制能力,那麼在物聯網建設中將具備資料的無限級聯傳遞與控制能力,使用一套框架形成一套解決方案。示意圖如下:
12.2 裝置連結器
IRunDevice裝置驅動介面繼承了服務的IServiceConnectorDevice介面,裝置驅動會實現RunServiceConnector介面函式,代表可以接收或執行來自服務例項傳遞過來的資料資訊。程式碼定義如下:
public interface IServiceConnectorDevice { /// <summary> /// 支行裝置聯結器 /// </summary> /// <param name="fromService"></param> /// <param name="toDevice"></param> /// <returns></returns> object RunServiceConnector(IFromService fromService, IServiceToDevice toDevice); }
12.3 服務連結器
IService介面繼承自IServiceConnector服務連結器,代表服務具備兩大職能:1、向裝置驅動傳送命令或資訊。2、接收裝置驅動處理命令或資訊的結果。程式碼如下:
public interface IServiceConnector { /// <summary> /// 裝置聯結器回撥函式,在這裡寫回調的處理結果 /// </summary> /// <param name="obj"></param> void ServiceConnectorCallback(object obj); /// <summary> /// 如果執行方出現異常,則返回給這個函式結果 /// </summary> /// <param name="ex"></param> void ServiceConnectorCallbackError(Exception ex); /// <summary> /// 聯結器事件,發起端 /// </summary> event ServiceConnectorHandler ServiceConnector; /// <summary> /// 確發事件介面 /// </summary> /// <param name="fromService"></param> /// <param name="toDevice"></param> void OnServiceConnector(IFromService fromService, IServiceToDevice toDevice); }
12.4 場景假設
裝置驅動實時採集感測器的資料資訊,然後通過OnDeviceObjectChanged事件介面把資料資訊傳遞給服務例項UpdateDevice介面函式,然後進行資料的快取。開啟服務執行緒,連線雲端服務並且定時上傳感測器的資料資訊。雲端服務下發控制指令command:control:1(注:命令控制1號編碼裝置),然後裝置驅動把命令下發給感測器,最終把結果返回給服務例項。
12.5 裝置驅動開發及注意事項
1.給服務例項傳遞資料資訊,通過OnDeviceObjectChanged事件。程式碼如下:
List<string> list = new List<string>(); list.Add(_devicePara.DeviceCode); list.Add(_devicePara.DeviceName); list.Add(_deviceDyn.Dyn.Flow.ToString()); list.Add(_deviceDyn.Dyn.Signal.ToString()); OnDeviceObjectChanged(list.ToArray());
2.接收服務例項傳遞的命令和資訊。程式碼如下:
public override object RunServiceConnector(IFromService fromService, IServiceToDevice toDevice) { Console.WriteLine(this.DeviceParameter.DeviceName+",接收到雲端指令:"+toDevice.Text); return this.DeviceParameter.DeviceName+",執行完成"; }
12.6 服務例項開發及注意事項
服務例項主要的職能是:快取資料、連線雲端服務並定時傳送資料、接收雲端命令資訊並傳遞給裝置驅動、接收驅動執行命令資訊的結果。
- 快取資料,程式碼如下:
public override void UpdateDevice(string devCode, object obj) { lock (_SyncObject) { if (obj != null) { if (obj is string[]) { string[] arr = (string[])obj; //OnServiceLog(String.Format("服務:{0} 接收到'{1}'的資料>>{2},{3}", ServiceName, arr[1], arr[2], arr[3])); if (arr.Length >= 2) { if (this._Cache.ContainsKey(devCode)) //判斷ID { this._Cache[devCode] = arr; } else { this._Cache.Add(devCode, arr); } } } } } }
2.連線雲端服務並定時傳送資料,程式碼如下:
private void Target_Service() { while (_IsRun) { try { if (_tcpClient != null) { lock (_SyncObject) { string content = String.Empty; foreach (KeyValuePair<string, string[]> kv in _Cache) { content += String.Join(",", kv.Value) + Environment.NewLine; } if (!String.IsNullOrEmpty(content)) { byte[] data = System.Text.Encoding.ASCII.GetBytes(content); this.OnSend(data); } } } else { this.ConnectServer(); } } catch (SocketException ex) { this.CloseSocket(); OnServiceLog(ex.Message); } catch (Exception ex) { OnServiceLog(ex.Message); } finally { System.Threading.Thread.Sleep(2000); } } }
3.接收雲端命令資訊並傳遞給裝置驅動
private void ReceiveCallback(IAsyncResult ar) { TcpClient socket = (TcpClient)ar.AsyncState; try { if (socket != null) { int read = socket.Client.EndReceive(ar); if (read > 0) { //處理資料.....................通知裝置 string text = System.Text.Encoding.ASCII.GetString(_Buffer, 0, read); OnServiceConnector(new FromService(this.ServiceName,this.ServiceKey),new ServiceToDevice("1",text,null,null) ); OnReceive(); } else { this.CloseSocket(); } } } catch (SocketException ex) { this.CloseSocket(); this.OnServiceLog(ex.Message); } catch (Exception ex) { this.OnServiceLog(ex.Message); } }
4.接收驅動執行命令資訊的結果
public override void ServiceConnectorCallback(object obj) { OnServiceLog(obj.ToString()); OnServiceLog("裝置已經處理完成指令"); }
12.7 宿主程式服務例項配置注意事項
static void Main(string[] args) { DeviceSelfDriver dev2 = new DeviceSelfDriver(); dev2.DeviceParameter.DeviceName = "網路裝置"; dev2.DeviceParameter.DeviceAddr = 1; dev2.DeviceParameter.DeviceID = "1"; dev2.DeviceDynamic.DeviceID = "1"; dev2.DeviceParameter.DeviceCode = "1"; dev2.DeviceParameter.NET.RemoteIP = "127.0.0.1"; dev2.DeviceParameter.NET.RemotePort = 9600; dev2.CommunicateType = CommunicateType.NET; dev2.Initialize("1"); IServer server = new ServerManager().CreateServer(new ServerConfig() { ServerName = "服務1", ComReadTimeout = 1000, ComWriteTimeout = 1000, NetReceiveTimeout = 1000, NetSendTimeout = 1000, ControlMode = ControlMode.Self, SocketMode = SocketMode.Tcp, StartReceiveDataFliter = true, ClearSocketSession = false, StartCheckPackageLength = true, CheckSameSocketSession = false, DeliveryMode = DeliveryMode.DeviceCode, }); server.AddDeviceCompleted += server_AddDeviceCompleted; server.DeleteDeviceCompleted+=server_DeleteDeviceCompleted; server.Start(); server.AddDevice(dev2); TestService.Service service=new TestService.Service(); service.IsAutoStart = true; server.AddService(service); while ("exit" == Console.ReadLine()) { server.Stop(); } }
12.8 執行效果
1.圖片
2.視訊
物聯網&整合技術(.NET) QQ群:54256083