近来由于工程需要,基于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. Visual Studio 2019本地不能运行Azure Functions

    最近一个项目,需要维护同事写得代码,主要是一堆基于 .net core 3.1 的 Azure Functions.想起2年前第一次接触 Azure Functions(那次是基于.net frame ...

  2. 我的新书《C++服务器开发精髓》终于出版啦

    一.千呼万唤始出来 亲爱的各位读者,我的新书<C++ 服务器开发精髓>终于终于终于与大家见面了,图书如下: 图书的封面设计很精美,当然内容一定不负众望.因出版社老师要求提供一张照片放到封面 ...

  3. Jenkins 流水线远程部署 .NET Core/Framework 到 IIS

    目录 Windows 安装 Git WebDeploy Windows 从节点 .NET Core 处理 IIS 处理项目 Jenkinsfile .NET Framework 安装环境 .NET F ...

  4. 学习Qt Charts-创建一个简单的折线图

    一.Qt Charts Qt Charts是基于Qt Graphics View实现的一个图表的组件,可以用来在QT GUI程序中添加现在风格的.可交互的.以数据为中心的图表,可以用作QWidget或 ...

  5. 7. Qt中与垃圾回收机制相关的替代方法(未完

    容器支持引用计数和写时复制 父对象和子对象 QPointer.QSharedPointer.QWeakReference 对象子类化 栈对象

  6. 11、linux的目录结构

    11.1.查看磁盘的id: blkid 11.2.linux目录类似一个倒挂的树: / 是所有目录的顶点,目录磁盘和分区是没有关联的,因此/下不同的目录会对应不同的磁盘的不同的分区: linux中硬盘 ...

  7. 10、ssh中scp、sftp程序详解

    每次都是全量拷贝,rsync是增量拷贝 10.1.scp的基本用法: -r:拷贝目录; -p: 保持属性: -l:限速设置; scp -P52113 /etc/hosts lc@172.16.1.41 ...

  8. 47、django工程(template)

    47.1.django 模板系统介绍: 1.说明: 我们可以直接将 HTML 硬编码到视图的python代码里,尽管这种技术便于解释视图是如何工作的,但却并不是一个好主意. def current_d ...

  9. 如何Spring Cloud Zuul作为网关的分布式系统中整合Swagger文档在同一个页面上

    本文不涉及技术,只是单纯的一个小技巧. 阅读本文前,你需要对spring-cloud-zuul.spring-cloud-eureka.以及swagger的配置和使用有所了解. 如果你的系统也是用zu ...

  10. 你真的了解 Session 和 Cookie 吗?

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 前言 ...