Mosquitto 和 JavaScript 示例不起作用 (Firefox)

Mosquitto and JavaScript Example not working (Firefox)

我想通过 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(用于 Linux Mint 89.0(64 位)的 Mozilla Firefox)给出错误消息 Firefox 无法建立与位于 wss://[=25 的服务器的连接=]:8081/mqtt.

也许有人可以提示我我的设置有什么问题?或者一个知道工作的 JavaScript 例子?

提前致谢, 克里斯托夫

首先增加连接超时时间,您目前设置为4秒,默认为30秒。因为 test.mosquitto.org 是一个完全 public 的经纪人,所以它经常受到人们的攻击(无论是测试东西还是只是不考虑他们在做什么)所以超时时间越长越好。

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

第三,即使连接,您实际上也没有做任何事情,您没有进行任何订阅,因此永远不会调用 on message 事件处理程序。你甚至没有一个 on connect 事件处理程序来知道你是否曾经干净地连接过。

例如

<!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>

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

本期描述的问题是 Mosquitto 不处理 HTTP/2 上的 websocket。更准确地说,Mosquitto 使用的 libwebsockets 使用 HTTP/2。 Chrome 正在使用基于 TLS 的 websockets,这确实有效。

有一些可能的解决方法:

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

As of version 2.0.14, Debian packages from http://repo.mosquitto.org have this issue fixed.

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 之后(一直滚动到底部)。问题依旧。