OPC client学习 2017.5.18

1.Websocket的使用

使用WebSocketSharp.dll文件

String url = "ws://127.0.0.1:9991/api/v1/devices/rfid";

var ws = new WebSocket(url);

ws.onMessage += (sender, e) => 

Console.WriteLine("received message:" + e.Data);//接受消息

ws.Connect();ws.Send("{\"id\":\"Device-01\",\"cmd\":\"connect\",\"data\":{},\"uuid\":\"1\"}");

ws.Send("{\"id\":\"Device-01\",\"cmd\":\"ping\",\"data\":{},\"uuid\":\"2\"}");
ws.Send("{\"id\":\"Device-01\",\"cmd\":\"rfid_report\",\"data\":{\"id\":\"Device-01\"},\"uuid\":\"3\"}");
ws.Send("{\"id\":\"Device-01\",\"cmd\":\"test_rfid_open\",\"data\":{\"id\":\"Device-01\"},\"uuid\":\"4\"}");
ws.Send("{\"id\":\"Device-01\",\"cmd\":\"test_rfid_clear\",\"data\":{\"id\":\"Device-01\"},\"uuid\":\"5\"}");
 ws.Send("{\"id\":\"Device-01\",\"cmd\":\"test_rfid_close\",\"data\":{\"id\":\"Device-01\"},\"uuid\":\"6\"}");
 Console.ReadKey();


2.服务器端的WebSocket服务会将客户端发送过去的消息包装成WebsocketSessionMsg类型的数据,服务器端的Actor接受到合法的消息时会判断,做出相应的响应

客户端和服务器端可能会建立多个Session,所以服务器端可能只会遍历其中的一条Session,避免出现过多的重复消息,但是目前无法判断消息的准确性,等添加了Token之后就可以解决这个问题。


3.OPC Client    首先创建OPCServer-->>>OPCGroups---->>>OPCGroup---->>>OPCItems---->>>OPCItems的句柄

可以通过MatrikonOPC来虚拟一个OPCServer进行数据仿真。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OPCAutomation;


namespace OpcClient
{
    class ConnectOpc
    {
        //private LoggerManagerUtil log = new LoggerManagerUtil();
        public BuhlerData buhlerData { get; set; } //布勒设备的工作状态 false表示秤上没有东西,true表示有
        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[49];
                int[] tmpCHandles = new int[49]; 
                for (int i = 1; i < 49; i++)
                {
                    tmpCHandles[i] = i;
                }
                //tmpIDs[1] = "Random.Boolean";
                //tmpIDs[2] = "Random.Boolean";
                //tmpIDs[3] = "Triangle Waves.Int4";
initialTmpId(tmpIDs);
                strItemIDs = (Array)tmpIDs;//必须转成Array型,否则不能调用AddItems方法
                lClientHandles = (Array)tmpCHandles;
                // 添加opc标签
                objItems.AddItems(49, ref strItemIDs, ref lClientHandles, out lserverhandles, out lErrors, RequestedDataTypes, AccessPaths);
                connectOpcState = true;
            }
            catch (Exception e) {
                //log.LogManage("连接OPC异常,原因:" + e.Message);
            }




        }


        public void initialTmpId(String[] tmpId) {
            //OPC启动标志
            tmpId[1] = "PL1.Bz_PLRUN1";
            //包装信息
            tmpId[2] = "TotalBags";
            //秤清空标志
            tmpId[3] = "PL1.Gross11";
            tmpId[4] = "PL1.Gross12";
            tmpId[5] = "PL1.Gross13";
            tmpId[6] = "PL1.Gross14";
            //混合机信息
            tmpId[7] = "521_HHJ_HZ"; //混合机频率
            tmpId[8] = "mixer1.T_DSV"; //混合机设定的混合所需总时间
            tmpId[9] = "mixer1.T_FSV"; //混合机设定的放料所需总时间


            //料仓开关信号
            tmpId[10] = "IB16";
            tmpId[11] = "IB17";
            tmpId[12] = "IB18";


            //料仓名称
            tmpId[13] = "Binlm.1";
            tmpId[14] = "Binlm.2";
            tmpId[15] = "Binlm.3";
            tmpId[16] = "Binlm.4";
            tmpId[17] = "Binlm.5";
            tmpId[18] = "Binlm.6";
            tmpId[19] = "Binlm.7";
            tmpId[20] = "Binlm.8";
            tmpId[21] = "Binlm.9";
            tmpId[22] = "Binlm.10";
            tmpId[23] = "Binlm.11";
            tmpId[24] = "Binlm.12";
            tmpId[25] = "Binlm.13";
            tmpId[26] = "Binlm.14";
            tmpId[27] = "Binlm.15";
            tmpId[28] = "Binlm.16";
            tmpId[29] = "Binlm.17";
            tmpId[30] = "Binlm.18";


            //料仓余量
            tmpId[31] = "BinWeight.1";
            tmpId[32] = "BinWeight.2";
            tmpId[33] = "BinWeight.3";
            tmpId[34] = "BinWeight.4";
            tmpId[35] = "BinWeight.5";
            tmpId[36] = "BinWeight.6";
            tmpId[37] = "BinWeight.7";
            tmpId[38] = "BinWeight.8";
            tmpId[39] = "BinWeight.9";
            tmpId[40] = "BinWeight.10";
            tmpId[41] = "BinWeight.11";
            tmpId[42] = "BinWeight.12";
            tmpId[43] = "BinWeight.13";
            tmpId[44] = "BinWeight.14";
            tmpId[45] = "BinWeight.15";
            tmpId[46] = "BinWeight.16";
            tmpId[47] = "BinWeight.17";
            tmpId[48] = "BinWeight.18";


        }


        //同步写
        public 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、付费专栏及课程。

余额充值