zoukankan      html  css  js  c++  java
  • OPC Winform客户端和WebSocket访问

    本文介绍了两种形式访问OPC服务器,并与其进行通信。

    基础环境:本地如果没有OPC环境,可以安装 KEPServerEX6.5 测试环境。

    一、Winform客户端访问与OPC通信

    1. 引入Interop.OPCAutomation.dll
    2. 新建OPCHelper.cs
     
    载入窗体时获取本地OPC服务器
    private void MainFrom_Load(object sender, EventArgs e)
    {
        GetLocalServer();
    }
    
    /// <summary>
    /// 枚举本地OPC服务器
    /// </summary>
    private void GetLocalServer()
    {
        try
        {
            var items = OPCHelper.GetLocalServer();
            foreach (string turn in items)
            {
                cmbServerName.Items.Add(turn);
            }
            if (cmbServerName.Items != null && cmbServerName.Items.Count > 0)
            {
                cmbServerName.SelectedIndex = 0;
            }
        }
        catch (Exception err)
        {
            MessageBox.Show("枚举本地OPC服务器出错:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
    3.创建OPCHelper.cs
    public class OPCHelper
    {
        /// <summary>
        /// 时长
        /// </summary>
        public const int JET_LAG = 8;
    
        #region 公共属性
    
        /// <summary>
        /// OPCServer Object
        /// </summary>
        public OPCServer KepServer { get; set; }
    
        /// <summary>
        /// OPCGroups Object
        /// </summary>
        public OPCGroups KepGroups { get; set; }
    
        /// <summary>
        /// OPCGroup Object
        /// </summary>
        public OPCGroup KepGroup { get; set; }
    
        /// <summary>
        /// OPCItems Object
        /// </summary>
        public OPCItems KepItems { get; set; }
    
        /// <summary>
        /// OPCItem Object
        /// </summary>
        public OPCItem KepItem { get; set; }
    
        /// <summary>
        /// 主机IP
        /// </summary>
        public string HostIP { get; set; }
    
        /// <summary>
        /// 主机名称
        /// </summary>
        public string HostName { get; set; }
    
        /// <summary>
        /// 连接状态
        /// </summary>
        public bool OPCConnected { get; set; }
    
        /// <summary>
        /// 客户端句柄
        /// </summary>
        public int ItemHandleClient { get; set; }
    
        /// <summary>
        /// 服务端句柄
        /// </summary>
        public int ItemHandleServer { get; set; }
    
        public List<string> opcItemsArray;
    
        public Dictionary<int, OPCItem> OPCItemDic;
    
        public List<OPCData> OPCDatas;
    
        #endregion
    
        public OPCHelper()
        {
            this.HostIP = string.Empty;
    
            this.HostName = string.Empty;
    
            this.OPCConnected = false;
    
            this.ItemHandleClient = 0;
    
            this.ItemHandleServer = 0;
    
            this.OPCDatas = new List<OPCData>();
    
            this.OPCItemDic = new Dictionary<int, OPCItem>();
    
        }
    
        public void Write(string value)
        {
            if (this.KepItems.Count > 0)
            {
    
                OPCItem bItem = this.KepItems.GetOPCItem(this.ItemHandleServer);
                int[] temp = new int[2] { 0, bItem.ServerHandle };
                Array serverHandles = (Array)temp;
                Array Errors;
                int cancelID;
    
                //KepGroup.AsyncWrite(1, ref serverHandles, ref values, out Errors, 2009, out cancelID);
    
                //KepItem.Write(Convert.ToInt32(txtWriteTagValue.Text));//这句也可以写入,但并不触发写入事件
    
                this.KepItem.Write(Convert.ToInt32(value));//这句也可以写入,但并不触发写入事件
                GC.Collect();
            }
        }
    
        public void SetDatas()
        {
    
            object value1;
    
            object quality1;
    
            object timeStamp1;
    
            var dataSourceNum = this.OPCDatas.Count();
    
            for (int i = 0, count = this.OPCItemDic.Keys.ToList().Count; i < count; i++)
            {
                var item = this.OPCItemDic.Values.ToList()[i];
                item.Read((short)OPCDataSource.OPCDevice, out value1, out quality1, out timeStamp1);
                OPCData data = null;
                for (int n = 0; n < dataSourceNum; n++)
                {
                    if (item.ItemID == this.OPCDatas[n].ItemID)
                    {
                        data = this.OPCDatas[n];
                        break;
                    }
                }
    
                if (data == null)
                {
                    this.OPCDatas.Add(new OPCData()
                    {
                        ItemID = item.ItemID,
    
                        Value = value1 != null ? value1.ToString() : string.Empty,
    
                        Quanlity = quality1 != null ? quality1.ToString() : string.Empty,
    
                        TimeStamp = timeStamp1 != null ? Convert.ToDateTime(timeStamp1.ToString()).AddHours(JET_LAG).ToString() : string.Empty
                    });
                }
                else
                {
                    for (int j = 0; j < dataSourceNum; j++)
                    {
                        if (this.OPCDatas[j].ItemID == data.ItemID)
                        {
                            this.OPCDatas[j].Value = value1 != null ? value1.ToString() : string.Empty;
    
                            this.OPCDatas[j].TimeStamp = timeStamp1 != null ? Convert.ToDateTime(timeStamp1.ToString()).AddHours(JET_LAG).ToString() : string.Empty;
    
                            this.OPCDatas[j].Quanlity = quality1 != null ? quality1.ToString() : string.Empty;
    
                            break;
                        }
                    }
                }
            }
        }
    
        /// <summary>
        /// 枚举本地OPC服务器
        /// </summary>
        public List<string> GetLocalServer()
        {
            List<string> servers = new List<string>();
            //获取本地计算机IP,计算机名称
            IPHostEntry IPHost = Dns.Resolve(Environment.MachineName);
            if (IPHost.AddressList.Length > 0)
            {
                this.HostIP = IPHost.AddressList[0].ToString();
            }
            else
            {
                return servers;
            }
    
            //通过IP来获取计算机名称,可用在局域网内
            IPHostEntry ipHostEntry = Dns.GetHostByAddress(this.HostIP);
            this.HostName = ipHostEntry.HostName.ToString();
            //获取本地计算机上的OPCServerName
            try
            {
                this.KepServer = new OPCServer();
                object serverList = this.KepServer.GetOPCServers(this.HostName);
                foreach (string turn in (Array)serverList)
                {
                    servers.Add(turn);
                }
            }
            catch (Exception err)
            {
                MessageBox.Show("枚举本地OPC服务器出错:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return servers;
        }
    }

    二、以WebSocket形式访问OPC

    允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    后端实现

    需要引入 Fleck

    private static List<IWebSocketConnection> allSockets;
    
    static void Main(string[] args)
    {
        FleckLog.Level = LogLevel.Debug;
        var server = new WebSocketServer("ws://0.0.0.0:9999");
        allSockets = new List<IWebSocketConnection>();
        server.Start(socket =>
        {
            socket.OnOpen = () =>
            {
                Open(socket);
            };
            socket.OnClose = () =>
            {
                Console.WriteLine("Close!");
                allSockets.Remove(socket);
            };
            socket.OnMessage = message =>
            {
                ReceivingClientMessage(message);
            };
        });
        var input = Console.ReadLine();
        while (input != "exit")
        {
            foreach (var socket in allSockets.ToList())
            {
                socket.Send(input);
            }
            input = Console.ReadLine();
        }
    }
    
    #region  Socket操作
    /// <summary>
    /// 发送消息至客户端
    /// </summary>
    /// <param name="message"></param>
    private static void SendMessageToClient(string message)
    {
        var input = message;// Console.ReadLine();
        foreach (var socket in allSockets.ToList())
        {
            socket.Send(input);
        }
    }
    
    /// <summary>
    /// 打开
    /// </summary>
    /// <param name="socket"></param>
    private static void Open(IWebSocketConnection socket)
    {
        Console.WriteLine("Open!");
        allSockets.Add(socket);
    }
    
    /// <summary>
    /// 接收客户端信息
    /// </summary>
    /// <param name="message"></param>
    static void ReceivingClientMessage(string json)
    {
        allSockets.ToList().ForEach(s => s.Send("Echo: " + json));
    }
    
    #endregion

    前端实现

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    <head>
        <title>websocket client</title>
        <script type="text/javascript">
            var start = function () {
                var inc = document.getElementById('incomming');
                var wsImpl = window.WebSocket || window.MozWebSocket;
                var form = document.getElementById('sendForm');
                var input = document.getElementById('sendText');
    
                inc.innerHTML += "connecting to server ..<br/>";
    
                // create a new websocket and connect
                window.ws = new wsImpl('ws://localhost:9999/');
    
                // when data is comming from the server, this metod is called
                ws.onmessage = function (evt) {
                    inc.innerHTML += evt.data + '<br/>';
                };
    
                // when the connection is established, this method is called
                ws.onopen = function () {
                    inc.innerHTML += '.. connection open<br/>';
                };
    
                // when the connection is closed, this method is called
                ws.onclose = function () {
                    inc.innerHTML += '.. connection closed<br/>';
                }
    
                form.addEventListener('submit', function (e) {
                    e.preventDefault();
                    
                    var val = input.value;
                    ws.send(val);
                    input.value = "";
                });
            }
            window.onload = start;
        </script>
    </head>
    <body>
        <form id="sendForm">
            <input id="sendText" placeholder="Text to send" />       
            <input type="submit" value="发送"></input>        
        </form>
        <pre id="incomming"></pre>
    </body>
    </html>

    资源下载地址:https://download.csdn.net/download/lincongqiong819/12406289

    一分辛苦一分才
  • 相关阅读:
    SQL-SQL介绍
    springcloud-服务注册与发现
    java基础-初识类
    java基础- Java编程规范与注释
    java基础-数据类型之殇
    java基础- 你真的了解运算符吗?
    java基础-控制流程语句
    java基础-对象的初始化
    TypeScript 联合类型
    TypeScript 元组
  • 原文地址:https://www.cnblogs.com/JoanLin-workNotes/p/12864013.html
Copyright © 2011-2022 走看看