简体   繁体   English

Mosquitto 和 JavaScript 示例不工作 (Firefox)

[英]Mosquitto and JavaScript Example not working (Firefox)

I would like to make a Websocket connection with TLS encryption to my mosquitto server.我想通过 TLS 加密与我的 mosquitto 服务器建立 Websocket 连接。 But I do not even get a simple example with the official mosquitto server running.但是我什至没有得到一个运行官方 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>

In the network Log I can see these statements:在网络日志中,我可以看到以下语句:

...
[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)) gives the error message Firefox can't establish a connection to the server at wss://test.mosquitto.org:8081/mqtt. Firefox(Mozilla Firefox for Linux Mint 89.0(64 位))在 wss://test.mosquitto.org:8081/mqtt 处提供错误消息Firefox 无法与服务器建立连接。

Maybe somebody can give me a hint what's wrong with my setup?也许有人可以给我一个提示,我的设置有什么问题? Or a know working JavaScript example?还是一个已知的有效 JavaScript 示例?

Thanks in advance, Christof在此先感谢,克里斯托夫

First increase the connection timeout, you currently have it set to 4 seconds, the default is 30 seconds.首先增加连接超时,你目前设置为 4 秒,默认为 30 秒。 Because test.mosquitto.org is a totally public broker it often gets hammered by people (either testing stuff or just not thinking what they are doing) so a longer timeout is better.因为 test.mosquitto.org 是一个完全公开的经纪人,所以它经常受到人们的抨击(要么是测试东西,要么只是不考虑他们在做什么),所以更长的超时时间会更好。

Secondly, having a clientID of test_client is VERY likely to clash with another client so your client will get kicked off the broker as soon as the other client tries to reconnect which will cause your client to reconnect causing a connect/disconnect loop.其次,拥有test_client的 clientID 很可能与另一个客户端发生冲突,因此一旦另一个客户端尝试重新连接,您的客户端就会被启动代理,这将导致您的客户端重新连接,从而导致连接/断开循环。 ClientID's need to unique across ALL clients connecting to the broker, I suggest you change this to a unique to you prefix combined with a random number. ClientID 需要在连接到代理的所有客户端中都是唯一的,我建议您将其更改为对您而言唯一的前缀和随机数。

Thirdly you don't actually do anything even if you connect, you make no subscriptions, so the on message event handler will never be called.第三,即使您连接,您实际上也没有做任何事情,您没有订阅,因此永远不会调用 on message事件处理程序。 You don't even have a on connect event handler to know if you ever get connected cleanly.您甚至没有 on connect事件处理程序来知道您是否曾经干净地连接。

eg例如

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

If your implementation works on Chrome but not Firefox then you might run into the issue mentioned here: https://github.com/eclipse/mosquitto/issues/1211 .如果您的实现适用于 Chrome 而不是 Firefox,那么您可能会遇到这里提到的问题: https : //github.com/eclipse/mosquitto/issues/1211 I ran into this issue as well with the same setup, eg Mosquitto v2 using Websockets over TLS.我使用相同的设置也遇到了这个问题,例如 Mosquitto v2 在 TLS 上使用 Websockets。 It connects fine on Chrome but Firefox does not accept a connection.它在 Chrome 上连接良好,但 Firefox 不接受连接。

The problem this issue describes is that Mosquitto does not handle websockets over HTTP/2.这个问题描述的问题是 Mosquitto 不能通过 HTTP/2 处理 websocket。 More precisely, libwebsockets used by Mosquitto uses HTTP/2.更准确地说,Mosquitto 使用的 libwebsockets 使用的是 HTTP/2。 Chrome is using websockets over TLS which does work. Chrome 正在使用基于 TLS 的 websockets,这确实有效。

There are a few possible workarounds:有几种可能的解决方法:

  1. Find a Mosquitto package with HTTP/2 disabled in libwebsocket.在 libwebsocket 中查找禁用 HTTP/2 的 Mosquitto 包。 This is by far the easiest solution.这是迄今为止最简单的解决方案。 Interestingly, the last comment in the above issue is that:有趣的是,上述问题的最后一条评论是:

As of version 2.0.14, Debian packages from http://repo.mosquitto.org have this issue fixed.从 2.0.14 版开始,来自http://repo.mosquitto.org 的Debian 软件包已修复此问题。

The changelog of version 2.0.14 does not mention this issue so maybe the Debian package maintainer solved it by building with a libwebsocket that has HTTP/2 disabled. 2.0.14 版本的变更日志没有提到这个问题,所以也许 Debian 包维护者通过构建一个禁用 HTTP/2 的 libwebsocket 解决了这个问题。

  1. Build your own Mosquitto with HTTP/2 disabled in libwebsocket.在 libwebsocket 中禁用 HTTP/2 构建您自己的 Mosquitto。

  2. Disable SPDY in firefox, so it uses HTTP/1.1.在 firefox 中禁用 SPDY,因此它使用 HTTP/1.1。 This might work during development but you can't expect all users to disable HTTP/2 in Firefox.这可能在开发过程中有效,但您不能期望所有用户都在 Firefox 中禁用 HTTP/2。 It is however an easy way to confirm that you're dealing with this issue.但是,这是确认您正在处理此问题的一种简单方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM