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

如何将Loxone WebSocket接收的数据转发到另一WebSocket连接

解决方案

问题根因

你现有代码的核心错误是:每次收到Loxone推送的事件时,才给客户端WebSocket服务注册connection事件监听,这会导致两个问题:

  • 已经连接成功的客户端永远收不到后续新的事件通知
  • 每次事件都新增一个重复的监听,后续新客户端连接时会收到大量重复的历史消息

实现思路

维持全局唯一的客户端连接池,仅在服务启动时绑定一次客户端连接/断开监听:

  • 客户端连接成功后加入连接池
  • 客户端断开连接后自动从池中移除
  • 收到Loxone事件时直接遍历连接池,给所有存活的客户端广播消息
  • 全程仅维持1条Loxone服务端连接,符合你的架构设计要求

修改后的完整代码

if (typeof LxCommunicator === 'undefined') {
    global.LxCommunicator = require('lxcommunicator');
}
//=== Node.js only ===
var fs = require('fs');
var WebSocket = require('ws');

// 请补全实际的私钥、证书文件读取逻辑
var privateKey = fs.readFileSync('./private.key'); //PkeyFile
var certificate = fs.readFileSync('./cert.pem'); //CertFile

var credentials = { key: privateKey, cert: certificate };
var https = require('https');

var httpsServer = https.createServer(credentials);
httpsServer.listen(60088);

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({
    server: httpsServer
});

// 新增:客户端连接池,存储所有存活的客户端WebSocket实例
const connectedClients = new Set();
// 仅绑定一次客户端连接监听
wss.on('connection', ws => {
    // 新客户端连接加入池
    connectedClients.add(ws);
    // 监听客户端断开,自动从池移除
    ws.on('close', () => {
        connectedClients.delete(ws);
    });
    // 可选:监听客户端错误,避免进程崩溃
    ws.on('error', err => {
        console.error('客户端连接错误', err);
        connectedClients.delete(ws);
    });
});


// Prepare our variables
// uuid是设备唯一标识,若getUUID未定义请自行实现
var uuid = getUUID(),
// delegateObj 包含所有可用的委托方法
delegateObj = {
    socketOnDataProgress: function socketOnDataProgress(socket, progress) {
        //console.log(progress);
    },
    socketOnTokenConfirmed: function socketOnTokenConfirmed(socket, response) {
        //console.log(response);
    },
    socketOnTokenReceived: function socketOnTokenReceived(socket, result) {
        //console.log(result);
    },
    socketOnTokenRefresh: function socketOnTokenRefresh(socket, newTkObj) {
        //console.log(newTkObj);
    },
    socketOnConnectionClosed: function socketOnConnectionClosed(socket, code) {
        process.exit(-1);
    },
    socketOnEventReceived: function socketOnEventReceived(socket, events, type) {
        events.forEach(function(event) {
            if(type === 2 || type ===3){ //2=灯光状态 3=模式状态
                var data = {};
                data["uuid"] = event.uuid;
                data["value"] = event.value;
                data['text'] = event.text;
                // 修改:遍历所有已连接客户端广播消息
                const msg = JSON.stringify(data);
                connectedClients.forEach(ws => {
                    // 仅给存活的客户端发消息
                    if (ws.readyState === WebSocket.OPEN) {
                        ws.send(msg);
                    }
                });
            }
        });
    }
},
// deviceInfo 是设备专属信息,类似浏览器的userAgent
deviceInfo;

// Node.js环境没有userAgent,用主机名替代
if (typeof window !== "undefined") {
    deviceInfo = window.navigator.userAgent;
} else {
    deviceInfo = require('os').hostname();
}
// 可选配置
// 如果不设置版本,LxCommunicator.WebSocket会自动拉取版本
// 该版本用于判断Miniserver是否支持加密和Token
//LxCommunicator.setConfigVersion("9.3.2.20");

// 获取LxCommunicator.WebSocketConfig构造器,简化后续调用
var WebSocketConfig = LxCommunicator.WebSocketConfig;

// 实例化配置对象,后续传给LxCommunicator.WebSocket
var config = new WebSocketConfig(WebSocketConfig.protocol.WS, uuid, deviceInfo, WebSocketConfig.permission.APP, false);

// 可选:绑定委托对象,即可响应委托回调
config.delegate = delegateObj;

// 实例化LxCommunicator.WebSocket,即实际和Loxone服务通信的WebSocket
var socket = new LxCommunicator.WebSocket(config);
// 只需提供主机、用户名、密码,即可打开和Miniserver的WebSocket连接
socket.open("loxoneserver", "loxoneuser", "loxonepassword").then(function() {
    socket.send("jdev/sps/enablebinstatusupdate").then(function(respons) {
        console.log("成功执行'" + respons.LL.control + "',返回码" + respons.LL.Code + ",返回值" + respons.LL.value);
    }, function(err) {
        console.error(err);
        process.exit(-1);
    });
}, function(e) {
    console.error(e);
});

补充说明

  • 若代码中getUUID方法未定义,可自行实现简单的UUID生成逻辑,或直接用固定的设备唯一标识
  • 生产环境建议增加消息堆积、客户端心跳检测逻辑,避免异常连接占用资源

内容的提问来源于stack exchange,提问作者jogoe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:30:04