近来由于工程需要,基于OPC DA 2.0搭建通用的取数模块,与远程webscoket服务端连接,并传输数据。在网上找了些资料,修改相应网友公开的源代码,基本达到要求,特供大家参考。

1.实体类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace OPC_DEMO
{
public class MyOPCItem
{
public string key{ get; set; }
public string Value { get; set; }
}
}

2.源代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OPCAutomation;
using System.Threading;
using System.IO;
using WebSocketSharp;
using Newtonsoft.Json; namespace OPC_DEMO
{
public partial class Form1 : Form
{
private OPCServer KepServer;
private OPCGroups KepGroups;
private OPCGroup KepGroup;
private OPCItems KepItems;
public WebSocket wsc;
private string JsonStr;
private MyOPCItem opc;
Dictionary<string, string> MAP_CLIENTHANDLE_TAG;
public OPCItem[] OPC_ITEMS_ADDED { get; private set; } public Form1()
{
InitializeComponent();
} #region OPC Client
/// <summary>
/// 自动连接OPC Server,并websocket连接服务器。
/// </summary>
private void KepServerLoad()
{
try
{ KepServer = new OPCServer();
//KepServer.Connect("FBoxOpcServer", "127.0.0.1");
KepServer.Connect("Kepware.KEPServerEx.V6","127.0.0.1");
// KepServer.Connect("Kepware.KEPServerEx.V5","127.0.0.1");
if (KepServer.ServerState == (int)OPCServerState.OPCRunning)
{
wsc = new WebSocket("ws://10.0.0.128:6690/WsServices");
wsc.Connect(); richTextBox1.Text = "OPC Server连接成功";
}
else
{
richTextBox1.Text = "OPC Server连接失败";
return;
}
}
catch (Exception ex)
{ richTextBox1.Text = "OPC Server连接失败," + ex.Message;
return;
} KepGroups = KepServer.OPCGroups;
Thread t1; // 开1个线程用于读取数据
t1 = new Thread(new ThreadStart(KepProcess));
t1.Start(); }
/// <summary>
/// 新建OPC Group并设置相应的属性,和触发改变事件
/// </summary>
public void KepProcess()
{
//KepGroup = KepGroups.Add("Channel.Device.Group");
KepGroup = KepGroups.Add("Channel1.Device1.Group");
KepGroup.UpdateRate = 1000;
KepGroup.IsActive = true;
KepGroup.IsSubscribed = true;
KepItems = KepGroup.OPCItems;
AddGroupItems();
//当KepGroup中数据发生改变的触发事件
KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange); // //item1 = KepItems.AddItem("My FBox.外泵站1.AI.流量1", 1);
// item1 = KepItems.AddItem("通道 1.设备 1.标记 1", 1);
////item2 = KepItems.AddItem("My FBox.外泵站1.DI.格栅运行", 2);
//item2 = KepItems.AddItem("通道 1.设备 1.标记 2", 2);
//item3 = KepItems.AddItem("通道 1.设备 1.test",3);
}
/// <summary>
/// 单独设立添加OPCItem方法,用来添加OPCItem
/// </summary>
public void AddGroupItems()
{
List<string> str = new List<string>(); str.Add("通道 1.设备 1.标记 1");
str.Add("通道 1.设备 1.标记 2");
str.Add("通道 1.设备 1.test"); List<OPCItem> ItemsAdd = new List<OPCItem>();
MAP_CLIENTHANDLE_TAG = new Dictionary<string, string>();
int n = 0;
foreach (string tag in str)
{
ItemsAdd.Add(KepItems.AddItem(tag, n));
MAP_CLIENTHANDLE_TAG.Add(n + "", tag);
n++;
} OPC_ITEMS_ADDED = ItemsAdd.ToArray();
} //当数据改变时触发的事件
//public delegate void DelegateShowMessage(string str);
public delegate void DelegateShowMessage(MyOPCItem str);
/// <summary>
/// 数据改变事件触发编写,调用委托事件远程发送。
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="ItemValues"></param>
/// <param name="Qualities"></param>
/// <param name="TimeStamps"></param>
public void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
Dictionary<string, string> tagValueMap = new Dictionary<string, string>();
string str = "";
// DelegateShowMessage show1 = new DelegateShowMessage(ShowMessage);
DelegateShowMessage show1 = new DelegateShowMessage(ShowMessage);
for (int i = 1; i <= NumItems; i++)
{
string clientHandle = ClientHandles.GetValue(i).ToString();
string tag = MAP_CLIENTHANDLE_TAG[clientHandle];
string val = ItemValues.GetValue(i).ToString();
//C# Dictionary 字典 添加数据
tagValueMap.Add(tag, val); //for (int i = 1; i <= NumItems; i++)
//{
// if (ClientHandles.GetValue(i).Equals(1))
// {
// str = "通道 1.设备 1.标记 1:" + ItemValues.GetValue(i).ToString();
// } // if (ClientHandles.GetValue(i).Equals(2))
// {
// str = "通道 1.设备 1.标记 2:" + ItemValues.GetValue(i).ToString();
// } // if (ClientHandles.GetValue(i).Equals(3))
// {
// str = "通道 1.设备 1.test:" + ItemValues.GetValue(i).ToString(); // }
}
//str = tagValueMap["通道 1.设备 1.标记 1"];
// str = tagValueMap["通道 1.设备 1.标记 2"];
//str = tagValueMap["通道 1.设备 1.标记 test"];
// BeginInvoke(show1, new string[] { str });
MyOPCItem json =ParseOPCData(tagValueMap);
BeginInvoke(show1, json); }
//public string ParseOPCData(Dictionary<string,string> tagValueMap)
//{
// foreach (var item in tagValueMap)
// {
// string key = item.Key;
// var value = item.Value;
// return "{"+"key:"+ key + "," + "Value:"+ value+"}";
// }
// return "";
//}
/// <summary>
/// 读Dictionary中的值,并传递给实体类。
/// </summary>
/// <param name="tagValueMap"></param>
/// <returns></returns>
public MyOPCItem ParseOPCData(Dictionary<string, string> tagValueMap)
{
opc = new MyOPCItem();
foreach (var item in tagValueMap)
{
opc.key = item.Key;
opc.Value = item.Value;
return opc;
}
return null;
}
//public void ShowMessage(string str)
//{
// //wsc.Send(JsonConvert.SerializeObject(str));
// // wsc.Send(str); // richTextBox1.AppendText(str + System.Environment.NewLine); //}
/// <summary>
/// websocket传递数据,和测试客户端显示。
/// </summary>
/// <param name="opc"></param>
public void ShowMessage(MyOPCItem opc)
{
wsc.Send(JsonConvert.SerializeObject(opc));
richTextBox1.AppendText(opc.Value + System.Environment.NewLine);
} #endregion
private void Form1_Load_1(object sender, EventArgs e)
{
KepServerLoad();
} private void Form1_FormClosing_1(object sender, FormClosingEventArgs e)
{
KepServer.Disconnect();
} }
}

3.结论

初步实现与websocket的数据对接,以json对象的形式传递,还需要websocket服务端将其反序列化为json字符串,并解析给前端使用。当然,这只是一个初步的Demo,其性能优化,线程占有的内存,以及稳定性都有待测试。

云平台制作(1)-OPC Client取数模块的制作的更多相关文章

  1. 重磅发布丨乐维监控:全面兼容云平台,助力企业DevOps转型升级!

    2019年伊始,我们迎来了乐维监控的又一重大功能更新——云平台监控,这将有效帮助企业将云上.云下数据聚合,方便统一化的监控管理与维护!未来,乐维监控每一次的产品功能及版本更新,我们都将第一时间于此发布 ...

  2. 完整部署CentOS7.2+OpenStack+kvm 云平台环境(4)--用OZ工具制作openstack镜像

    在部署openstack云平台环境的时候,需要上传镜像到glance. 首先下载iso镜像,这里下载了centos6.5镜像,放到/usr/local/src目录下然后用OZ工具制作openstack ...

  3. Redis之高可用、集群、云平台搭建(非原创)

    文章大纲 一.基础知识学习二.Redis常见的几种架构及优缺点总结三.Redis之Redis Sentinel(哨兵)实战四.Redis之Redis Cluster(分布式集群)实战五.Java之Je ...

  4. Redis之高可用、集群、云平台搭建

    原文:Redis之高可用.集群.云平台搭建 文章大纲 一.基础知识学习二.Redis常见的几种架构及优缺点总结三.Redis之Redis Sentinel(哨兵)实战四.Redis之Redis Clu ...

  5. 使用 Velero 跨云平台迁移集群资源到 TKE

    概述 Velero 是一个非常强大的开源工具,可以安全地备份和还原,执行灾难恢复以及迁移Kubernetes群集资源和持久卷,可以在 TKE 平台上使用 Velero 备份.还原和迁移集群资源,关于如 ...

  6. 完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建

    公司在IDC机房有两台很高配置的服务器,计划在上面部署openstack云平台虚拟化环境,用于承载后期开发测试和其他的一些对内业务.以下对openstack的部署过程及其使用做一详细介绍,仅仅依据本人 ...

  7. A亚马逊WS网上系列讲座——怎么样AWS云平台上千万用户的应用建设

    用户选择云计算平台构建应用程序的一个重要原因是高弹性的云平台和可扩展性. 面向Internet应用程序通常需要支持用户使用大量,但要建立一个高度可扩展.具有一定的挑战,高度可用的应用程序,只有立足AW ...

  8. 腾讯基于Kubernetes的企业级容器云平台GaiaStack (转)

    GaiaStack介绍 GaiaStack是腾讯基于Kubernetes打造的容器私有云平台.这里有几个关键词: 腾讯:GaiaStack可服务腾讯内部所有BG的业务: Kubernetes:Gaia ...

  9. OpenStack(二)——使用Kolla部署OpenStack-allinone云平台

    (1).Kolla概述 Kolla是OpenStack下用于自动化部署的一个项目,它基于docker和ansible来实现,其中docker主要负责镜像制作和容器管理,ansible主要负责环境的部署 ...

随机推荐

  1. 使用sign签名发送请求

    import CryptoJS from "crypto-js"; import urlencode from "urlencode"; methods:{ a ...

  2. 用Java语言编写的迷宫小游戏软件

    可查看本项目的github 源码链接,撒娇打滚求 star 哦~~ღ( ´・ᴗ・ ` )比心 本仓库代码是经过 eclipse 编译运行过的,一般情况下将本仓库代码下载下来之后,使用 eclipse ...

  3. 温故知新,.Net Core遇见JWT(JSON Web Token)授权机制方案

    什么是JWT JWT (JSON Web Token) 是一个开放标准,它定义了一种以紧凑和自包含的方法,用于在双方之间安全地传输编码为JSON对象的信息. 因此,简单来说,它是JSON格式的加密字符 ...

  4. mapboxgl 互联网地图纠偏插件(二)

    前段时间写的mapboxgl 互联网地图纠偏插件(一)存在地图旋转时瓦片错位的问题. 这次没有再跟 mapboxgl 的变换矩阵较劲,而是另辟蹊径使用 mapboxgl 的自定义图层,重新写了一套加载 ...

  5. python之set集合,基础篇

    集合:set 特点:1>.无序 ,因为集合是无序的,所以不可用下标值查询,也不可切片2>.去重 ,一个集合内不能有两个相同的元素3>.可添加,可删除,不可修改等等4>.集合内的 ...

  6. 2300+字!在不同系统上安装Docker!看这一篇文章就够了

    辰哥准备出一期在Docker跑Python项目的技术文,比如在Docker跑Django或者Flask的网站.跑爬虫程序等等. 在Docker跑Python程序的时候不会太过于细去讲解Docker的基 ...

  7. Mysql Limit 调优

    建表与插入数据 SQL对比 基本数据 创建表 CREATE TABLE student ( id int(10) NOT NULL AUTO_INCREMENT, name varchar(25) D ...

  8. AcWing 1289. 序列的第k个数

    BSNY 在学等差数列和等比数列,当已知前三项时,就可以知道是等差数列还是等比数列. 现在给你 整数 序列的前三项,这个序列要么是等差序列,要么是等比序列,你能求出第k项的值吗. 如果第k项的值太大, ...

  9. 对象池技术和通用实现GenericObjectPool

    对象池技术其实蛮常见的,比如线程池.数据库连接池 他们的特点是:对象创建代价较高.比较消耗资源.比较耗时: 比如 mysql数据库连接建立就要先建立 tcp三次握手.发送用户名/密码.进行身份校验.权 ...

  10. Docker:docker部署Sqlite3数据库

    1.依赖Ubuntu系统安装sqlite3生成镜像 dockerfile文件 FROM ubuntu:trusty RUN sudo apt-get -y update RUN sudo apt-ge ...