You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器运行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:24:55