zoukankan      html  css  js  c++  java
  • 《连载 | 物联网框架ServerSuperIO教程》- 12.服务接口的开发,以及与云端双向交互

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍

    《连载 | 物联网框架ServerSuperIO教程》1.4种通讯模式机制。

    《连载 | 物联网框架ServerSuperIO教程》2.服务实例的配置参数说明

    《连载 | 物联网框架ServerSuperIO教程》- 3.设备驱动介绍

    《连载 | 物联网框架ServerSuperIO教程》-4.如开发一套设备驱动,同时支持串口和网络通讯。

    《连载 | 物联网框架ServerSuperIO教程》- 5.轮询通讯模式开发及注意事项。

    《连载 | 物联网框架ServerSuperIO教程》- 6.并发通讯模式开发及注意事项

    《连载 | 物联网框架ServerSuperIO教程》- 7.自控通讯模式开发及注意事项

    《连载 | 物联网框架ServerSuperIO教程》- 8.单例通讯模式开发及注意事项

    《连载 | 物联网框架ServerSuperIO教程》- 9. 协议过滤器,解决一包多发、粘包、冗余数据

    《连载 | 物联网框架ServerSuperIO教程》- 10.持续传输大块数据流的两种方式(如:文件)

    《连载 | 物联网框架ServerSuperIO教程》- 11.实现设备(驱动)与设备(驱动)交互和级联控制。


    目       录

    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     服务实例开发及注意事项

         服务实例主要的职能是:缓存数据、连接云端服务并定时发送数据、接收云端命令信息并传递给设备驱动、接收驱动执行命令信息的结果。

    1. 缓存数据,代码如下:
    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.视频


    1.[连载]《C#通讯(串口和网络)框架的设计与实现》

    2.[开源]C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍

    2.应用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)构建系统的整体方案

    3.C#工业物联网和集成系统解决方案的技术路线(数据源、数据采集、数据上传与接收、ActiveMQ、Mongodb、WebApi、手机App)

    5.ServerSuperIO开源地址:https://github.com/wxzz/ServerSuperIO

    物联网&集成技术(.NET) QQ群54256083 

  • 相关阅读:
    2019.3.18 IP通信基础
    2019.3.11 IP通信基础
    2019.3.7 IP通信基础
    2019.3.4 IP通信基础
    员工贷项目优劣点总结
    mysql事务_事务隔离级别详解
    mysql锁
    mybatis错误——java.io.IOException: Could not find resource com/xxx/xxxMapper.xml
    小问题
    关于char是否能表示一个中文
  • 原文地址:https://www.cnblogs.com/lsjwq/p/6103075.html
Copyright © 2011-2022 走看看