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,这确实有效。
有一些可能的解决方法:
- 找到一个在 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 来解决它。
在 libwebsocket 中禁用 HTTP/2 构建您自己的 Mosquitto。
在 firefox 中禁用 SPDY,因此它使用 HTTP/1.1。这可能在开发过程中有效,但您不能期望所有用户在 Firefox 中禁用 HTTP/2。然而,这是确认您正在处理此问题的简单方法。
更新:不幸的是,在使用 https://mosquitto.org/download/ 中的 Ubuntu 软件包 ppa 安装 Mosquitto 2.0.14 之后(一直滚动到底部)。问题依旧。
我想通过 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,这确实有效。
有一些可能的解决方法:
- 找到一个在 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 来解决它。
在 libwebsocket 中禁用 HTTP/2 构建您自己的 Mosquitto。
在 firefox 中禁用 SPDY,因此它使用 HTTP/1.1。这可能在开发过程中有效,但您不能期望所有用户在 Firefox 中禁用 HTTP/2。然而,这是确认您正在处理此问题的简单方法。
更新:不幸的是,在使用 https://mosquitto.org/download/ 中的 Ubuntu 软件包 ppa 安装 Mosquitto 2.0.14 之后(一直滚动到底部)。问题依旧。