如果都配好,运行方面遇到问题,可以直接跳过前面的直接去看解决问题和编码详解部分
目录
服务端
1 准备
1.1 VMwareWorkstation
用来安装虚拟机,官方下载即可,测试环境使用的16.x版本。
1.2 Windows 7 64位(虚拟机)
服务端,用来部署opc服务。 选择win7是因为它够老且不会再自动更新,由于选择使用utgard,它对操作系统版本要求比较多,操作系统太新了会报错,随操作系统自动更新也会报错,例如win10的1909版本更新到21xx版本,就不能运行了。
win7 64位专业版镜像
链接:https://pan.baidu.com/s/1QVYiX_fcPPwOwexIINyjHw
提取码:j31x
1.3 opc模拟器
虚拟机上的opc服务,opc服务端。
MatrikonOPCSimulation
链接:https://pan.baidu.com/s/13PtADnoellrd2cAJsEz2Tw
提取码:c06r
1.4 win10(如果需要)
如果一定要使用win10,推荐1806或者1909版本,再新(比如win10 版本21H2)的就不用试了,肯定用不了,只能用虚拟机。
选择好系统之后需要关闭自动更新,关闭防火墙,特此整理了手顺:
系统基础设置:
虚拟机装机时需指定一个用户,默认admin,改成Administrator
新系统,ping宿主机能通,宿主机ping虚拟机不通,虚拟机关掉防火墙,能ping通
关掉系统自动更新:services.msc -> Windows Update 禁用,恢复都改成无操作; gpedit.msc 计算机配置 –> 管理模板 –> Windows组件–> Windows更新 –> 配置自动更新 –> 禁用
新增一个硬盘,系统自动重启,硬盘新建卷(用于安装应用,不安装在C盘)
创建FTP目录(用于和宿主机共享文件)
切换administrator用户,创建密码,加到DCOM组
安装OPC软件(这里是力控):
右键以管理员身份运行安装文件,除了“安装资源程序”其它都正常安装,最后重启一次。
右键以管理员身份运行ForceControl,如果不弹出确认弹窗,表示当前用户权限是可以的
开发,选择启动程序,除了opcserver其它都可以关掉
运行opc client:
matrikon explorer/opc client,连接PCAuto Server,连接正常。至此,opcserver安装成功并且连接正常。
系统权限设置:
Administrator创建密码
计算机管理,Administrator加到DCOM 用户组里
组件管理,计算机修改属性
组件管理,OpcEnum修改权限
组件管理,opcserver修改权限
注:如果是32位软件运行在64位系统,需要执行 mmc comexp.msc /32 打开组件管理,64位的是dcomcnfg
2 安装VMware
根据官方指导安装即可。
3 安装Windows虚拟机
1core、4G、20G即可。
4 Windows7虚拟机基本设置
4.1 关闭防火墙(DA需要)
4.2 默认用户为Administrator(例子中是admin),修改登录密码(例如:)
4.3 计算机 –> 右键属性 –> 远程设置
4.4 使用物理机执行远程连接,用admin/登录成功即可
5 Windows7系统备份
为防止系统配置错误,建议对已配置好的虚拟机进行系统备份。本地是把分配的系统文件夹直接压缩了一份,恢复时直接删掉现有的文件夹,再解压出来。(如果有更好的解决方案欢迎交流)。
6 安装MatrikonOPCSimulation
把安装包直接复制到虚拟机,默认安装即可。
6.1电脑配置
第七步下面是配置opc服务的用户名与6.1的用户名必须保持一直即可
7 组件服务相关配置
7.1 配置虚拟机登录权限
打开计算机管理,添加或修改用户到Dcom用户组。
打开组件服务程序
右键我的电脑
点击第一个编辑限制,点击添加,输入admin,确定。
把admin的远程访问勾上,确定。
重复上述步骤,把几个都点了。
7.4 OPCEnum配置
这个配置权限不对,会报class未注册的异常。
交互式用户灰色变为可选的,重新注册OpcEnum.exe
②如果OpcEnum.exe存在System32目录下,则在CMD中执行以下命令
C:\Windows\System32\OpcEnum.exe /regserver
③如果OpcEnum.exe存在SysWOW64目录下,则在CMD中执行以下命令
C:\Windows\SysWOW64\OpcEnum.exe /regserver
7.3 DCOM服务配置
这里以力控为例,其它同理。如果配置错误,会导致报连接失败的相关错误。
↓ 这是matrikon的服务名称
和上面一个套路,把admin加进去并给上权限。
客户端
1 Windows 10 64 客户端
本地开发环境
2 Java运行环境
jdk8
3 代码及配置项
3.1 maven依赖 <!--utgard --> <dependency> <groupId>org.openscada.external</groupId> <artifactId>org.openscada.external.jcifs</artifactId> <version>1.2.25</version> </dependency> <dependency> <groupId>org.openscada.jinterop</groupId> <artifactId>org.openscada.jinterop.core</artifactId> <version>2.1.8</version> </dependency> <dependency> <groupId>org.openscada.jinterop</groupId> <artifactId>org.openscada.jinterop.deps</artifactId> <version>1.5.0</version> </dependency> <dependency> <groupId>org.openscada.utgard</groupId> <artifactId>org.openscada.opc.dcom</artifactId> <version>1.5.0</version> </dependency> <dependency> <groupId>org.openscada.utgard</groupId> <artifactId>org.openscada.opc.lib</artifactId> <version>1.5.0</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.61</version> </dependency>
3.2 同步定时读取
package com.ruoyi.opc.util; import java.util.concurrent.Executors; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.core.JIString; import org.jinterop.dcom.core.JIVariant; import org.openscada.opc.lib.common.ConnectionInformation; import org.openscada.opc.lib.da.AccessBase; import org.openscada.opc.lib.da.DataCallback; import org.openscada.opc.lib.da.Item; import org.openscada.opc.lib.da.ItemState; import org.openscada.opc.lib.da.Server; import org.openscada.opc.lib.da.SyncAccess; public class UtgardAsyncLoop { public static void main(String[] args) throws Exception { // 连接信息 final ConnectionInformation ci = new ConnectionInformation(); ci.setHost("192.168.222.129"); // 虚拟机ip ci.setDomain(""); // 域,为空就行 ci.setUser("admin"); // 虚拟机登录的用户名 ci.setPassword(""); // 虚拟机登录密码 ci.setClsid("F8582CF2-XXXX-11D0-XXXX-00C0F0"); //MatrikonOPCSimulation的注册表ID,可以在“组件服务”里看到,如果不对则需要去注册列表里找 final String itemId = "g1.test1"; // MatrikonOPCSimulation上配置的项的名字,没有实际PLC,用的模拟器:simulator // 启动服务 final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor()); try { // 连接到服务 server.connect(); // add sync access, poll every 500 ms,启动一个同步的access用来读取地址上的值,线程池每500ms读值一次 // 这个是用来循环读值的,只读一次值不用这样 final AccessBase access = new SyncAccess(server, 500); // 这是个回调函数,就是读到值后执行这个打印,是用匿名类写的,当然也可以写到外面去 access.addItem(itemId, new DataCallback() { @Override public void changed(Item item, ItemState itemState) { int type = 0; try { type = itemState.getValue().getType(); // 类型实际是数字,用常量定义的 } catch (JIException e) { e.printStackTrace(); } System.out.println("监控项的数据类型是:-----" + type); System.out.println("监控项的时间戳是:-----" + itemState.getTimestamp().getTime()); System.out.println("监控项的详细信息是:-----" + itemState); // 如果读到是short类型的值 if (type == JIVariant.VT_I2) { short n = 0; try { n = itemState.getValue().getObjectAsShort(); } catch (JIException e) { e.printStackTrace(); } System.out.println("-----short类型值: " + n); } // 如果读到是字符串类型的值 if(type == JIVariant.VT_BSTR) { // 字符串的类型是8 JIString value = null; try { value = itemState.getValue().getObjectAsString(); } catch (JIException e) { e.printStackTrace(); } // 按字符串读取 String str = value.getString(); // 得到字符串 System.out.println("-----String类型值: " + str); } } }); // start reading,开始读值 access.bind(); // wait a little bit,有个10秒延时 Thread.sleep(60 * 1000); // stop reading,停止读取 // access.unbind(); } catch (final JIException e) { System.out.println(String.format("%08X: %s", e.getErrorCode(), server.getErrorMessage(e.getErrorCode()))); if (null != server) { server.disconnect(); } } } }
3.3 异步定时读取
package com.ruoyi.opc.util; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.core.JIString; import org.jinterop.dcom.core.JIVariant; import org.openscada.opc.lib.common.ConnectionInformation; import org.openscada.opc.lib.da.*; import java.util.*; import java.util.concurrent.Executors; /** * @author renqing * @date 07/27/2021 */ public class UtgardPsp { private static final int PERIOD = 100; private static final int SLEEP = 1000 * 60 * 10; public static void main(String[] args) throws Exception { // 连接信息 final ConnectionInformation ci = new ConnectionInformation(); ci.setHost("192.168.222.129"); // 本机IP ci.setDomain(""); // 域,为空就行 ci.setUser("admin"); // 本机上自己建好的用户名 ci.setPassword(""); // 用户名的密码 ci.setClsid("F8582CF2-XXXX-11D0-XXXX-00C0F0"); //注册表ID,可以在“组件服务”里看到 Map<String, String> items = new HashMap<String, String>(); items.put("itemId1","g1.test1"); items.put("itemId2","g1.test2"); items.put("itemId3","g1.test3"); items.put("itemId4","g1.test4"); // 启动服务 final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor()); // 连接到服务 server.connect(); AccessBase access = new Async20Access(server, PERIOD, true); // 循环一遍所有的itemid Set<String> keys = items.keySet(); for (String key : keys) { String val = items.get(key); access.addItem(val, new DataCallback() { private int count; @Override public void changed(Item item, ItemState itemstate) { System.out.println("[" + (++count) + "],ItemName:[" + item.getId() + "],value:" + itemstate.getValue()); } }); } access.bind(); // Thread.sleep(SLEEP); while(true) { } // access.unbind(); // server.dispose(); } }
3.4 同步读取
public String readSync(String itemIds, Server server) throws JIException, AddFailedException, IllegalArgumentException, UnknownHostException, NotConnectedException, DuplicateGroupException { Group group = server.addGroup(); Item item = group.addItem(itemIds); JIVariant value = item.read(false).getValue(); return value.getObjectAsString2(); }
3.5 根据服务ID连接,规避使用clsid
/** * Create a new instance and a new DCOM session * @param host the host to contact * @param user the user to use for authentication * @param password the password to use for authentication * @param domain The domain to use for authentication * @throws IllegalArgumentException * @throws UnknownHostException * @throws JIException */ public ServerList ( final String host, final String user, final String password, final String domain ) throws IllegalArgumentException, UnknownHostException, JIException { this ( JISession.createSession ( domain, user, password ), host ); } /** 使用ip、用户名、密码、域名(可以为空),创建ServerList对象, * 可以推出OPC服务列表,服务名称对应的进程名(ProgressId),使用ProgId可以推出clsid */ Collection<ClassDetails> detailsList = serverList.listServersWithDetails( new Category[] { Categories.OPCDAServer10, Categories.OPCDAServer20, Categories.OPCDAServer30 }, new Category[] {}); for (final ClassDetails details : detailsList) { System.out.println("---------------->ClsId=" + details.getClsId() + " ProgId=" + details.getProgId() + " Description=" + details.getDescription()); } serverList.getClsIdFromProgId(progId); // progId是服务名,例如:Kepware.KEPServerEX.V6
3.6 server断线重连
// 使用自动重连控制器包装一次server AutoReconnectController controller = new AutoReconnectController(serverInstance); controller.connect();
3.7 遍历item
FlatBrowser flatBrowser = server.getFlatBrowser(); if (flatBrowser == null) { return false; } try { Collection<String> collection = flatBrowser.browse(); return collection.containsAll(list); } catch (Exception e) { e.printStackTrace(); } try { TreeBrowser treeBrowser = server.getTreeBrowser(); Branch browse = treeBrowser.browse(); Collection<Branch> branches = browse.getBranches(); for (Branch branch : branches) { Collection<Leaf> leaves = branch.getLeaves(); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (JIException e) { e.printStackTrace(); }
已测试通过
MatrikonOPC
KEPServer
GRM(广州巨控)
北京力控。读取OPC数据是成功了,但是给操作系统带来的副作用很大。网络设备、磁盘管理器等都变得不可操作,整个操作系统变得很混乱。例如:我的电脑右键属性报错、本地连接右键报错、磁盘管理器报错等,初步怀疑和力控软件有关。
测试未通过
北京亚控(组态王)。理论上是可以的,后面没有精力再试了。
异常处理
异常及错误码
1、未安装
Class not registered. If you are using a DLL/OCX , please make sure it has “DllSurrogate” flag set. Faq A(6) in readme.html. [0x80040154]
org.jinterop.dcom.common.JIException: The system cannot find the file specified. Is the COM Server present ? Please check DCOMCNFG for it’s listing. [0x]
2、用户名/密码写错
org.jinterop.dcom.common.JIException: Access is denied, please check whether the [domain-username-password] are correct. Also, if not already done please check the GETTING STARTED and FAQ sections in readme.htm. They provide information on how to correctly configure the Windows machine for DCOM access, so as to avoid such exceptions. [0x00000005]
原因:首先检查错误提示的配置信息是否有误,如果都正确,则原因可能是你访问的当前用户没有该访问权限。
解决方法:(但是网上针对win10版本是21H2的是不行的,如果系统是这个版本果断放弃吧,下载个虚拟机按照上面个的步骤可以通)
(1)、打开注册列表,
选择HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00D9B6}
(2)、右键点击[权限]>>【高级】>>[所有者]>>添加opc用户到权限项目中,点击应用,确定。
3、服务ip写错
org.jinterop.dcom.common.JIException: An internal error occurred. [0x8001FFFF]
4、写错Clsid
org.jinterop.dcom.common.JIException: Class not registered. If you are using a DLL/OCX , please make sure it has “DllSurrogate” flag set. Faq A(6) in readme.html. [0x80040154]
大坑注意
如果用的是组件服务中的CLSID,报0x的错误,就去用注册表中的靠谱
解决办法
5、属性都写对,服务端配置错误
org.jinterop.dcom.common.JIException: Access is denied. [0x]
6、opc服务崩了
org.jinterop.dcom.common.JIException: Server execution failed. [0x]
7、服务安装不正确,考虑换个版本试试
org.jinterop.dcom.common.JIException: Interface not registered. [0x]
8、windows版本太高,出现在win10及以上操作系统中,win –> 设置 –> 系统 –> 关于,查看版本,类似2xxx的都不行,最高1909。类似这种都不行,需要回退版本。
org.jinterop.dcom.common.JIException: Message not found for errorCode: 0x
9、错误编码汇总
0xA
The server process could not be started because the configured identity is incorrect. Check the username and password.
0x
Unspecified Error
0xBA
RPC_S_SERVER_UNAVAILABLE
The RPC server is unavailable
0xBF
远程过程调用失败且未执行
0xE
E_OUTOFMEMORY
Not enough memory to complete the requested operation. This can happen any time the server needs to allocate memory to complete the requested operation.
0x
Couldn’t create connection with advise sink,
Reason for error: There is a problem resolving the computer name.
Solution: This problem can be solved by specifying the IP address of the server instead of specifying the computer name
0x
0x appears in the OPC Client application when it succeeds in launching an OPC Server or OpcEnum, but fails to receive a reply from either of the applications. This error could be caused under several conditions: On the OPC Server PC, the OPC Client User Account does not have the right Access Control List (ACL) permissions in the System-Wide DCOM settings, Access Permissions, Edit Default.
On the OPC Client PC, the OPC Server User Account does not have the right Access Control List (ACL) permissions in the System-Wide DCOM settings, Access Permissions, Edit Limits.
On the OPC Client PC, the DCOM Default Impersonation Level is set to “Anonymous” instead of “Identify”, and the “ANONYMOUS LOGON” Access Control Entry (ACE) does not exist in the OPC Client PC, Access Control List (ACL) permissions in the System-Wide DCOM settings, Access Permissions, Edit Limits.
Failure to obtain a CLSID
OPC Client application failed to find the OPC Server. The two most common causes are:
Failure to find the OPC server in the Windows Registry
Failure to connect to OPCENUM.EXE
Failed to connect to 2.0 data access interface for group … Falling back to 1.0 interface
可能原因:计算机重名或局域网DNS服务故障,或者在不同子网中
0x8001FFFF
设备连接数量超过OPCserver支持的连接量,需要重启电脑即可
0x
The object invoked has
disconnected from its clients.
Re-initialize your OPC Server Connection.
0x
There is no connection for
this connection ID
0x
Need to run the object to
perform this operation
0x
Uninitialized object
0x
Class not registered The OPC Server, or a component needed to
make the OPC connection is not registered
with Windows. This may mean that you simply
need to register a DLL or OCX file.
0x
Interface not registered The OPC Server does not support the
interface that you are trying to connect to.
Examples may include Item Browsing,
Asynchronous I/O or OPC DA v2.x or 3.x
interfaces etc.
0xf3 Invalid class string The GUID/CLSID of the specified OPC Server
is not valid.
0x
• Unable to
impersonate DCOM
Client
• Unknown OLE status
code
DCOM security problem, typically on the
Client side. This error typically occurs when
trying to specify a callback address for
Asynchronous I/O.
0x
Cannot Connect Error typically occurs when a call is made to
Advise on the connection point. This often
means that OPCPROXY.DLL is not the same
version on your different computers.
0x
The system cannot find the
file specified.
Re-install your software.
0x
Access is denied. You need to configure your DCOM Security
settings. See our DCOM Tutorial:
http://www.softwaretoolbox.com/dcom Page 6 of 7
Hex Code Description Resolution
0x
The parameter is incorrect. The OPC Server has rejected your request,
indicating that the parameter(s) you specified
are not valid for the type of request being
made. You will need more details on the
actual OPC calls being made between the
Client and Server.
0xd The service did not respond
to the start or control request
in a timely fashion.
Specific to Windows Services. The service did
not start within the allowed time-frame. This
indicates an initialization problem with the
Windows service.
0xb4 This operation returned
because the timeout period
expired.
This is a timeout. You may need to increase
your timeout settings.
0xea A floating-point underflow
occurred at the RPC server.
0x Incompatible version of the
RPC stub.
0x
Server execution failed There is a problem with the OPC Server
preventing it from being started by Windows.
This may be the result of file-permissions,
DCOM Security permissions, or a lack of
resources.
0x
No such interface supported The OPC Server does not support the
interface that you are trying to connect to.
Examples may include Item Browsing,
Asynchronous I/O or OPC DA v2.x or 3.x
interfaces etc.
0x
Unspecified error The most common message seen, that yields
the least information. In these cases you often
need to check the event-logs at your OPC
Server for more information.
0xa The server process could not
be started because the
configured identity is
incorrect. Check the
username and password.
DCOM Configuration permissions. Modify the
identity that the application should run under,
perhaps specify a named account or choose
“Interactive User’.
0xba The RPC server is
unavailable.
The OPC Server could not be contacted. This
is usually the result of a firewall blocking the
application
0xC0000034
(1)org.jinterop.dcom.common.JIException: Message not found for errorCode:0xC0000034
原因:未启动RemoteRegistry和Windows Management Instrumentation服务。
解决方法:打开控制面板,点击【管理工具】—>>【服务】,启动RemoteRegistry和Windows ManagementInstrumentation服务。
10、
OPCServer:使用Matrikon OPC Server Simulation – ioufev – 博客园 使用Matrikon OPC Server Simulation https://www.cnblogs.com/ioufev/p/9366426.html
查看用法
总结
1、如果不清楚用户组针对哪些服务权限,就不操作用户组。给所需要的服务权限控制上直接加用户就可以了。
2、经测试,客户端的用户名和服务端的一样都是admin,但是密码不同,依然可以调用opc服务端。
3、连接失败的原因,基本都由于服务端的配置(包括授权配置、网络配置),或者程序中参数写错(或找错)导致。
今天的文章
opc客户端和服务端的区别_opc服务器与opc客户端分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/81057.html