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

如何实现XForms与MQTT Websocket的JS集成(XSLTForms+Paho)

XForms + MQTT 集成入站消息处理方案(XSLTForms + Paho JS + Mosquitto)

问题场景

用XSLTForms实现XForms与MQTT的集成,通过WebSocket借助Paho JS库对接Mosquitto消息代理,已能通过xf:load发送静态字符串消息,但无法将MQTT入站消息传入XForms内部。最初尝试在onMessageArrived函数中触发自定义JS事件,再用xf:action响应,但不清楚事件注册与载荷接收的实现方式,最终摸索出三种可行方案。

解决方案

方案1:JS触发隐藏的xf:trigger

在页面中添加一个隐藏的xf:trigger,当MQTT消息到达时,用JS模拟点击该trigger,触发绑定的XForms动作:

<!-- 隐藏的消息触发按钮 -->
<xf:trigger id="mqttMsgTrigger" style="display:none">
  <xf:label>MQTT消息触发</xf:label>
  <xf:action ev:event="DOMActivate">
    <!-- 更新实例数据存储消息 -->
    <xf:setvalue ref="instance('mqttData')/msg" value="javascript:getCurrentMqttMsg()"/>
  </xf:action>
</xf:trigger>

对应的JS逻辑:

// 全局变量暂存消息内容
let currentMqttMsg;

function onMessageArrived(message) {
  currentMqttMsg = message.payloadString;
  // 触发隐藏trigger的点击事件
  document.getElementById('mqttMsgTrigger').click();
}

function getCurrentMqttMsg() {
  return currentMqttMsg;
}

方案2:直接调度DOMActivate事件

无需额外trigger元素,使用XSLTForms内置的XsltForms_xmlevents.dispatch方法直接调度事件:

<xf:model id="mainModel">
  <!-- 绑定DOMActivate事件处理逻辑 -->
  <xf:action ev:event="DOMActivate" ev:target="mqttMsgHandler">
    <xf:setvalue ref="instance('mqttData')/msg" value="javascript:getCurrentMqttMsg()"/>
  </xf:action>
</xf:model>

对应的JS逻辑:

let currentMqttMsg;

function onMessageArrived(message) {
  currentMqttMsg = message.payloadString;
  // 直接向model调度DOMActivate事件
  XsltForms_xmlevents.dispatch(
    document.getElementById('mainModel'),
    'DOMActivate',
    { targetId: 'mqttMsgHandler' }
  );
}

方案3:自定义事件绑定到xf:model

为xf:model设置ID作为事件源,创建自定义事件并绑定XForms动作响应:

<xf:model id="mainModel">
  <!-- 绑定自定义事件mqtt-message-arrived -->
  <xf:action ev:event="mqtt-message-arrived">
    <!-- 通过event('data')获取事件携带的消息载荷 -->
    <xf:setvalue ref="instance('mqttData')/msg" value="event('data')"/>
  </xf:action>
</xf:model>

对应的JS逻辑:

function onMessageArrived(message) {
  const modelNode = document.getElementById('mainModel');
  // 创建带消息载荷的自定义事件
  const mqttEvent = new CustomEvent('mqtt-message-arrived', {
    detail: message.payloadString,
    bubbles: true,
    cancelable: true
  });
  // 向model分发事件
  modelNode.dispatchEvent(mqttEvent);
}

从XForms实例传递参数调用JS函数

如果需要从XForms实例中读取数据,调用JS函数发送MQTT消息,可参考以下实现:

<xf:trigger>
  <xf:label>发送MQTT消息</xf:label>
  <xf:action ev:event="DOMActivate">
    <xf:script>
      sendMqttMsg(instance('sendData')/content);
    </xf:script>
  </xf:action>
</xf:trigger>

对应的JS发送函数:

function sendMqttMsg(content) {
  const message = new Paho.MQTT.Message(content);
  message.destinationName = "test/topic";
  client.send(message);
}

完整测试代码

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
<xf:model xmlns:xf="http://www.w3.org/2002/xforms" id="mainModel">
  <xf:instance id="mqttData">
    <data>
      <msg></msg>
    </data>
  </xf:instance>
  <xf:instance id="sendData">
    <data>
      <content>Hello from XForms!</content>
    </data>
  </xf:instance>

  <!-- 方案3的自定义事件响应逻辑 -->
  <xf:action ev:event="mqtt-message-arrived">
    <xf:setvalue ref="instance('mqttData')/msg" value="event('data')"/>
  </xf:action>
</xf:model>

<h1>XForms + MQTT 测试页面</h1>

<!-- 显示收到的MQTT消息 -->
<xf:output ref="instance('mqttData')/msg">
  <xf:label>收到的消息:</xf:label>
</xf:output>

<!-- 发送消息按钮 -->
<xf:trigger>
  <xf:label>发送测试消息</xf:label>
  <xf:action ev:event="DOMActivate">
    <xf:script>
      sendMqttMsg(instance('sendData')/content);
    </xf:script>
  </xf:action>
</xf:trigger>

<!-- 引入本地Paho JS库(请自行下载放置到对应路径) -->
<script src="mqttws31.min.js"></script>
<script>
  // MQTT客户端初始化
  const client = new Paho.MQTT.Client("localhost", 9001, "xsltforms-test-client");
  
  client.onConnectionLost = function(responseObj) {
    console.log("连接断开: " + responseObj.errorMessage);
  };
  
  client.onMessageArrived = function(message) {
    // 方案3的事件分发逻辑
    const modelNode = document.getElementById('mainModel');
    const mqttEvent = new CustomEvent('mqtt-message-arrived', {
      detail: message.payloadString,
      bubbles: true,
      cancelable: true
    });
    modelNode.dispatchEvent(mqttEvent);
  };
  
  client.connect({
    onSuccess: function() {
      console.log("MQTT连接成功");
      client.subscribe("test/topic");
    }
  });
  
  function sendMqttMsg(content) {
    const message = new Paho.MQTT.Message(content);
    message.destinationName = "test/topic";
    client.send(message);
  }
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:43:22