【问题标题】:Mosquitto and JavaScript Example not working (Firefox)Mosquitto 和 JavaScript 示例不工作 (Firefox)
【发布时间】:2021-11-03 21:21:59
【问题描述】:

我想通过 TLS 加密与我的 mosquitto 服务器建立 Websocket 连接。但是我什至没有得到一个运行官方 mosquitto 服务器的简单示例。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Hello MQTT World</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
    // Initialize a mqtt variable globally
    console.log(mqtt)


// connection option
const options = {
        clean: true, // retain session
      connectTimeout: 4000, // Timeout period
      // Authentication information
      clientId: 'test_client',
}

// Connect string, and specify the connection method by the protocol
// ws Unencrypted WebSocket connection
// wss Encrypted WebSocket connection
// mqtt Unencrypted TCP connection
// mqtts Encrypted TCP connection
// wxs WeChat applet connection
// alis Alipay applet connection
const connectUrl = 'wss://test.mosquitto.org:8081/mqtt'
const client = mqtt.connect(connectUrl,options)

client.on('reconnect', (error) => {
    console.log('reconnecting:', error)
})

client.on('error', (error) => {
    console.log('Connection failed:', error)
})

client.on('message', (topic, message) => {
  console.log('receive message:', topic, message.toString())
})
</script>
</head>
<body>
    <div id="logger"></div>
</body>
</html>

在网络日志中我可以看到这些语句:

...
[1]</</</v.prototype._setupReconnect
https://unpkg.com/mqtt/dist/mqtt.min.js:1:14126
[1]</</</v.prototype._cleanUp
https://unpkg.com/mqtt/dist/mqtt.min.js:1:15261
[1]</</</v.prototype._setupStream/this.connackTimer<
https://unpkg.com/mqtt/dist/mqtt.min.js:1:7007
(Async: setTimeout handler) [1]</</</v.prototype._setupStream
https://unpkg.com/mqtt/dist/mqtt.min.js:1:6920
[1]</</</v.prototype._reconnect
https://unpkg.com/mqtt/dist/mqtt.min.js:1:13732
[1]</</</v.prototype._setupReconnect/e.reconnectTimer<
https://unpkg.com/mqtt/dist/mqtt.min.js:1:14195
(Async: setInterval handler)
...

Firefox (Mozilla Firefox for Linux Mint 89.0 (64-bit)) 给出错误消息 Firefox 无法在 wss://test.mosquitto.org:8081/mqtt 建立与服务器的连接。

也许有人可以提示我的设置有什么问题?还是一个已知的有效 JavaScript 示例?

提前致谢, 克里斯托夫

【问题讨论】:

  • 目前test.mosquitto.org上的websocket接口好像不太好,建议你明天再试试或者换个例子服务器(比如hivemq的)

标签: javascript ssl firefox mosquitto


【解决方案1】:

如果您的实现适用于 Chrome 而不是 Firefox,那么您可能会遇到此处提到的问题:https://github.com/eclipse/mosquitto/issues/1211。我使用相同的设置也遇到了这个问题,例如 Mosquitto v2 在 TLS 上使用 Websockets。它在 Chrome 上可以正常连接,但 Firefox 不接受连接。

此问题描述的问题是 Mosquitto 无法通过 HTTP/2 处理 websocket。更准确地说,Mosquitto 使用的 libwebsockets 使用的是 HTTP/2。 Chrome 正在使用基于 TLS 的 websockets,这确实有效。

有几种可能的解决方法:

  1. 在 libwebsocket 中查找禁用 HTTP/2 的 Mosquitto 包。这是迄今为止最简单的解决方案。有趣的是,上一期的最后一条评论是:

从 2.0.14 版开始,来自 http://repo.mosquitto.org 的 Debian 软件包已修复此问题。

changelog of version 2.0.14 没有提到这个问题,所以也许 Debian 软件包维护者通过构建一个禁用 HTTP/2 的 libwebsocket 解决了这个问题。

  1. 在 libwebsocket 中禁用 HTTP/2 来构建您自己的 Mosquitto。

  2. 在 firefox 中禁用 SPDY,因此它使用 HTTP/1.1。这可能在开发过程中有效,但您不能期望所有用户都在 Firefox 中禁用 HTTP/2。但是,这是确认您正在处理此问题的一种简单方法。

更新:不幸的是,在使用来自https://mosquitto.org/download/ 的 Ubuntu 软件包 ppa 安装 Mosquitto 2.0.14 之后(一直滚动到底部)。问题依然存在。

【讨论】:

    【解决方案2】:

    首先增加连接超时,你目前设置为 4 秒,默认为 30 秒。因为 test.mosquitto.org 是一个完全公开的代理,所以它经常受到人们的抨击(测试东西或者只是不考虑他们在做什么)所以更长的超时时间会更好。

    其次,具有test_client 的 clientID 很可能与另一个客户端发生冲突,因此一旦另一个客户端尝试重新连接,您的客户端就会被踢出代理,这将导致您的客户端重新连接,从而导致连接/断开连接环形。 ClientID 需要在连接到代理的所有客户端中都是唯一的,我建议您将其更改为您的唯一前缀和随机数。

    第三,即使你连接了,你实际上也没有做任何事情,你没有订阅,所以 on message 事件处理程序永远不会被调用。你甚至没有 onconnect 事件处理程序来知道你是否曾经干净地连接。

    例如

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Hello MQTT World</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
    <script>
        // Initialize a mqtt variable globally
        console.log(mqtt)
    
    
    // connection option
    const options = {
            clean: true, // retain session
          connectTimeout: 30000, // Timeout period increased to 30 seconds
          // Authentication information
          clientId: 'foobar_test_random' + Math.floor(Math.random() * 10000),
    }
    
    // Connect string, and specify the connection method by the protocol
    // ws Unencrypted WebSocket connection
    // wss Encrypted WebSocket connection
    // mqtt Unencrypted TCP connection
    // mqtts Encrypted TCP connection
    // wxs WeChat applet connection
    // alis Alipay applet connection
    const connectUrl = 'wss://test.mosquitto.org:8081'
    const client = mqtt.connect(connectUrl,options)
    
    //actually subscribe to something on a sucessfull connection
    client.on('connect', (connack) => {
      client.subscribe('$SYS/#')
    })
    
    client.on('reconnect', (error) => {
        console.log('reconnecting:', error)
    })
    
    client.on('error', (error) => {
        console.log('Connection failed:', error)
    })
    
    client.on('message', (topic, message) => {
      console.log('receive message:', topic, message.toString())
    })
    </script>
    </head>
    <body>
        <div id="logger"></div>
    </body>
    </html>
    

    【讨论】:

    • 感谢您的提示!
    • 与此同时,我将浏览器更改为 Chromium,并且可以正常工作。我确实设法获得了订阅并将其附加到 HTML 元素。但我想获取 JSON 数据,但这是行不通的。使用纯文本它可以工作。也许你有另一个提示我需要处理什么?
    • 消息的一个例子是`owntracks/user/galahad {"_type":"location","acc":15,"alt":630,"batt":56,"bs" :1,"conn":"m","created_at":1630968608,"lat":45.8052892,"lon":12.5361642,"t":"u","tid":"ad","tst":1630968603 ,"vac":150,"vel":1} `
    • 特别是我对 LAT 和 LON 以及时间戳“created_at”感兴趣
    • 在 Stack Overflow 上发布一个新问题作为新帖子是合适的。这让其他人有机会回答它,并让有类似问题的人可以找到它。如果它作为评论发布,他们将找不到它。
    猜你喜欢
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 2016-04-18
    相关资源
    最近更新 更多