OPC服务2017.5.25

在连接服务器时,对于连接服务器的工具类只能创建一次,要不然在有心跳程序的情况下会出现服务器与客户端连接正常但是重复连接服务器的过程,心跳程序是针对一次连接但是出现断开的情况而设计的。

一。出现的问题

1.配置文件写错,搞了半天才发现,下次别手贱乱改配置文件

2.在启动服务的OnStart方法里要开启一个新的线程连接Java服务器以及OPC服务器,在OnMessage最好也开启一个新的线程处理接受到的消息

2.Json数据转换,对于内嵌的Json数据,需要使用类作为容器容纳此内嵌的Json数据 

eg.{
    "Name": "cy",
    "Age": 28,
    "Alive": false,
    "FavoriteFilms": null,
    "Child": {
      "Name": "lj",
      "Age": 12,
      "Alive": true,
      "Child": null
    }
  }

Child这个字段的Json数据就需要使用一个类Child来表示

使用方法

Class:ConnectBean

[DataContract]
    class ConnectBean
    {
        [DataMember(Order = 0, IsRequired = true)]
        public String id { get; set; }
        [DataMember(Order = 1)]
        public String cmd { get; set; }
        [DataMember(Order = 2)]
        public Data data { get; set; }
        [DataMember(Order = 3)]
        public String uuid { get; set; }


        public ConnectBean() {
        }


        public ConnectBean(String id, String cmd, Data data, String uuid) {
            this.id = id;
            this.cmd = cmd;
            this.data = data;
            this.uuid = uuid;
        }




    }


Class:Data

 [DataContract]
    class Data
    {
        [DataMember(Order = 0, IsRequired = true)]
        public String Value { get; set; }
        [DataMember(Order = 1)]
        public String Quality { get; set; }
        [DataMember(Order = 2)]
        public String TimeStamp { get; set; }
    }


public static String Bean2JsonMethod(ConnectBean cb) {
            //将ConnectBean对象序列化为Json
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(cb.GetType());
            //创建存储区为内存流
            MemoryStream ms = new MemoryStream();
            //将Json字符串写入内存流中
            serializer.WriteObject(ms, cb);
            System.IO.StreamReader reader = new StreamReader(ms);
            ms.Position = 0;
            string strRes = reader.ReadToEnd();
            reader.Close();
            ms.Close();
            return strRes;
        }



当时用序列化和反序列化转换数据格式的时候使用[Serializable]会导致转化出来的Json数据变成"<cmd>k__BackingField"这种格式,需要使用 [DataContract]这种方法才行。

3.

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\

InstallUtil   路径地址\OpcClient.exe  安装服务

InstallUtil   /u  路径地址\OpcClient.exe  卸载服务

net start 服务名   启动服务

 net stop服务名   停止服务 



4.当使用记录日志的方法时,如果多个线程同时操作一个日志文件可能会出现异常,导致服务崩溃,避免多个线程会同时操作一个日志文件。

5.链接OPC服务器设备源码

 class ConnectOpc
    {
        //private LoggerManagerUtil log = new LoggerManagerUtil();
        public Boolean connectOpcState { get; set; } = false;//OPC服务器是否连接成功的标志位
        public ConnectServer cs { get; set; }
        private OPCServer objServer;//OPCServer类
        private OPCGroups objGroups;//通过OPCServer创建OPCGroups组
        private OPCGroup objGroup;//
        private OPCItems objItems;
        private Array strItemIDs;//Items的数组形式,2个Item上的话,需要创建3个空间,使用后边2个
        private Array lClientHandles;//客户端句柄,通过Items创建,2个Item上的话,值为0,1,2,一般使用1和2
        private Array lserverhandles;//OPC服务器端句柄,添加OPC标签Items后通过OPC服务器端赋值
        private Array lErrors;//添加OPC标签Items时OPC服务器端返回的错误信息
        //  int ltransID_Rd = 1;
        // int lCancelID_Rd;
        private object RequestedDataTypes = null;
        private object AccessPaths = null;
        //   Array lerrors_Rd;
        private Array lErrors_Wt;
        private int lTransID_Wt = 2;
        private int lCancelID_Wt;




        public void ConnectOpcMethod() {
            try {
                //(1)创建opc server对象
                objServer = new OPCServer();
                //连接opc server
                objServer.Connect("Matrikon.OPC.Simulation.1", null);
                //objServer.Connect("OPCServer.WinCC.1", null);            
                //(2)建立一个opc组集合
                objGroups = objServer.OPCGroups;
                int a = objServer.ServerState;
                //(3)建立一个opc组
                objGroup = objGroups.Add(null); //Group组名字可有可无
                                                //(4)添加opc标签
                objGroup.IsActive = true; //设置该组为活动状态,连接PLC时,设置为非活动状态也一样
                objGroup.IsSubscribed = true; //设置异步通知
                objGroup.UpdateRate = 200;
                objServer.OPCGroups.DefaultGroupDeadband = 0;
                objGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
                //objGroup.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(AsyncReadComplete);
                //objGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(AsyncWriteComplete);
                objItems = objGroup.OPCItems; //建立opc标签集合
                string[] tmpIDs = new string[4];
                int[] tmpCHandles = new int[4];
                for (int i = 1; i < 4; i++)
                {
                    tmpCHandles[i] = i;
                }
                tmpIDs[1] = "Random.Boolean";
                tmpIDs[2] = "Random.Boolean";
                tmpIDs[3] = "Triangle Waves.Int4";
                strItemIDs = (Array)tmpIDs;//必须转成Array型,否则不能调用AddItems方法
                lClientHandles = (Array)tmpCHandles;
                // 添加opc标签
                objItems.AddItems(3, ref strItemIDs, ref lClientHandles, out lserverhandles, out lErrors, RequestedDataTypes, AccessPaths);
                connectOpcState = true;
            }
            catch (Exception e) {
                //log.LogManage("连接OPC异常,原因:" + e.Message);
            }




        }


        //同步写
        private void Write_Syn(String str)
        {
            try {
                if (!connectOpcState) {
                    ConnectOpcMethod();
                }
                int NumItems = 1;
                int[] Handles = new int[2];
                Handles[1] = Convert.ToInt32(lserverhandles.GetValue(3));
                Array ServerHandles = (Array)(Handles);
                object[] data = new object[2];
                //data[1] = (object)Write1.Text;
                data[1] = (object)str;
                Array Values = (Array)data;
                Array Errors;
                objGroup.SyncWrite(NumItems, ref ServerHandles, ref Values, out Errors);
            }
            catch (Exception ex) {
                //log.LogManage("向OPC写入数据异常,原因:" + ex.Message);
                DisConnect();
            }
        }


        //异步写完成
        //private void AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
        //{
        //    throw new NotImplementedException();
        //}


        //订阅方式读
        private void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            try {
                //为了测试,所以加了控制台的输出,来查看事物ID号
                //Console.WriteLine("********"+TransactionID.ToString()+"*********");


                //订阅方式读,读到的数据通过ConnectServer的Send方法发送给Java服务器
                for (int i = 0; i < NumItems; i++)
                {




                    if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 1)
                    {
                        if (ItemValues.GetValue(i + 1) != null)
                        {
                            //this.Value1.Text = ItemValues.GetValue(i + 1).ToString();
                            //this.Quality1.Text = Qualities.GetValue(i + 1).ToString();
                            //this.TimeStamp1.Text = TimeStamps.GetValue(i + 1).ToString();
                            //ConnectBean cb = new ConnectBean("1","test_read","",2);
                            //cs.send(Bean2JsonUtil.Bean2JsonMethod(cb));
                            String Value= ItemValues.GetValue(i + 1).ToString();
                            String Quality = Qualities.GetValue(i + 1).ToString();
                            String TimeStamp = TimeStamps.GetValue(i + 1).ToString();
                            String msg = OpcDataDealUtil.OpcDataDealMethod(Value,Quality,TimeStamp);
                            cs.send(msg);
                        }
                    }
                    if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 2)
                    {
                        if (ItemValues.GetValue(i + 1) != null)
                        {
                            //this.Value2.Text = ItemValues.GetValue(i + 1).ToString();
                            //this.Quality2.Text = Qualities.GetValue(i + 1).ToString();
                            //this.TimeStamp2.Text = TimeStamps.GetValue(i + 1).ToString();
                            //ConnectBean cb = new ConnectBean("1", "test_read", "", 2);
                            //cs.send(Bean2JsonUtil.Bean2JsonMethod(cb));
                            String Value = ItemValues.GetValue(i + 1).ToString();
                            String Quality = Qualities.GetValue(i + 1).ToString();
                            String TimeStamp = TimeStamps.GetValue(i + 1).ToString();
                            String msg = OpcDataDealUtil.OpcDataDealMethod(Value, Quality, TimeStamp);
                            cs.send(msg);
                        }
                    }
                    if (Convert.ToInt32(ClientHandles.GetValue(i + 1)) == 3)
                    {
                        if (ItemValues.GetValue(i + 1) != null)
                        {
                            //this.Value3.Text = ItemValues.GetValue(i + 1).ToString();
                            //this.Quality3.Text = Qualities.GetValue(i + 1).ToString();
                            //this.TimeStamp3.Text = TimeStamps.GetValue(i + 1).ToString();
                            //ConnectBean cb = new ConnectBean("1", "test_read", "", 2);
                            //cs.send(Bean2JsonUtil.Bean2JsonMethod(cb));
                            String Value = ItemValues.GetValue(i + 1).ToString();
                            String Quality = Qualities.GetValue(i + 1).ToString();
                            String TimeStamp = TimeStamps.GetValue(i + 1).ToString();
                            String msg = OpcDataDealUtil.OpcDataDealMethod(Value, Quality, TimeStamp);
                            cs.send(msg);
                        }
                    }
                }
            }
            catch (Exception e) {
                //log.LogManage("订阅数据异常,原因:" + e.Message);
                DisConnect();
            }
        }


        //关闭OPC连接
        private void DisConnect()
        {
            try {
                if (objServer != null)
                {
                    objServer.Disconnect();               
                }
                connectOpcState = false;
                //关闭kepserver进程,这个跟OPC操作无关
                /*
                foreach ( Process oneProcess in Process.GetProcesses())
                {
                if (oneProcess.ProcessName == "ServerMain")
                oneProcess.Kill();
                }
                */
            }
            catch (Exception  ex) {
                //log.LogManage("关闭OPC连接异常,原因:" + ex.Message);
                connectOpcState = false;
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值