浏览器运行OPC UA客户端遇连接拒绝问题求解决方案
问题根源
浏览器的安全模型禁止直接发起原始TCP连接,包括OPC UA默认使用的opc.tcp协议。你用Go编译的WebAssembly在浏览器环境中继承了这个限制——Go的net.Dial接口在浏览器Wasm环境下无法创建TCP套接字,所以无论你用localhost、私有IP还是公共服务器,都会出现连接拒绝或地址解析失败的错误。
可行解决方案
方案一:使用OPC UA over WebSocket(推荐)
OPC UA标准支持WebSocket绑定,这是浏览器能直接兼容的网络协议,无需额外代理。
步骤1:修改Node-OPCUA服务器,启用WebSocket端点
在你现有的服务器代码中添加WebSocket类型的端点配置:
const opcua = require("node-opcua"); const server = new opcua.OPCUAServer({ port: 4840, resourcePath: "/UA/MyServer", serverInfo: { applicationUri: "urn:MyServer", productUri: "urn:MyServerProduct" }, // 同时保留TCP端点,添加WebSocket端点 endpoints: [ { endpointUrl: "opc.tcp://0.0.0.0:4840/UA/MyServer", securityMode: opcua.MessageSecurityMode.None, securityPolicy: opcua.SecurityPolicy.None }, { endpointUrl: "ws://0.0.0.0:8080/UA/MyServer", // WebSocket端点 securityMode: opcua.MessageSecurityMode.None, securityPolicy: opcua.SecurityPolicy.None } ] }); // 后续服务器启动逻辑不变 server.start(function() { console.log("Server is listening on port ", server.endpoints[0].port); console.log("WebSocket endpoint: ", server.endpoints[1].endpointUrl); });
步骤2:使用浏览器兼容的OPC UA客户端库
直接在HTML中引入浏览器版的OPC UA客户端,通过WebSocket连接服务器:
<html> <head> <meta charset="utf-8"/> <script src="https://unpkg.com/@opcua/client-browser@2.12.0/dist/opcua-client-browser.min.js"></script> </head> <body> <script> const { OPCUAClient, MessageSecurityMode, SecurityPolicy } = window.opcua; async function connectToServer() { const client = OPCUAClient.create({ endpoint_must_exist: false, securityMode: MessageSecurityMode.None, securityPolicy: SecurityPolicy.None }); try { // 连接WebSocket端点 await client.connect("ws://localhost:8080/UA/MyServer"); const session = await client.createSession(); console.log("成功连接到OPC UA服务器"); // 示例:读取变量值 const dataValue = await session.readVariableValue("ns=2;s=MyVariable"); console.log("读取到的值:", dataValue.value.value); await session.close(); await client.disconnect(); } catch (err) { console.error("连接失败:", err.message); } } connectToServer(); </script> </body> </html>
方案二:搭建WebSocket转OPC UA TCP代理
如果无法修改目标OPC UA服务器(比如第三方服务器不支持WebSocket),可以搭建一个中间代理,将浏览器的WebSocket请求转发为OPC UA TCP请求。
步骤1:编写Node.js代理服务
const WebSocket = require('ws'); const { OPCUAClient, MessageSecurityMode, SecurityPolicy } = require('node-opcua'); // 启动WebSocket服务,监听8081端口 const wss = new WebSocket.Server({ port: 8081 }); wss.on('connection', async (ws) => { let client, session; // 处理浏览器发送的消息 ws.on('message', async (rawMsg) => { try { const msg = JSON.parse(rawMsg); switch(msg.type) { case 'connect': // 初始化OPC UA客户端并连接到目标服务器 client = OPCUAClient.create({ endpoint_must_exist: false, securityMode: MessageSecurityMode.None, securityPolicy: SecurityPolicy.None }); await client.connect(msg.endpoint); session = await client.createSession(); ws.send(JSON.stringify({ type: 'connected' })); break; case 'read': // 读取指定节点的值 const dataValue = await session.readVariableValue(msg.nodeId); ws.send(JSON.stringify({ type: 'readResult', value: dataValue.value.value })); break; // 可扩展其他操作:写入、订阅等 } } catch (err) { ws.send(JSON.stringify({ type: 'error', message: err.message })); } }); // 连接关闭时清理资源 ws.on('close', async () => { if (session) await session.close(); if (client) await client.disconnect(); }); }); console.log("代理服务启动,监听ws://localhost:8081");
步骤2:浏览器端通过代理连接服务器
<html> <head> <meta charset="utf-8"/> </head> <body> <script> const ws = new WebSocket('ws://localhost:8081'); ws.onopen = () => { // 告诉代理要连接的OPC UA TCP端点 ws.send(JSON.stringify({ type: 'connect', endpoint: 'opc.tcp://localhost:4840/UA/MyServer' })); }; ws.onmessage = (event) => { const resp = JSON.parse(event.data); switch(resp.type) { case 'connected': console.log("通过代理连接成功"); // 请求读取变量 ws.send(JSON.stringify({ type: 'read', nodeId: 'ns=2;s=MyVariable' })); break; case 'readResult': console.log("读取到的值:", resp.value); break; case 'error': console.error("代理返回错误:", resp.message); break; } }; </script> </body> </html>
内容的提问来源于stack exchange,提问作者Bennison J
相关产品推荐
相关产品推荐

