无法通过angular8中的ngx-mqtt连接到MQTT代理 [英] Unable to connect to MQTT broker via ngx-mqtt in angular8

查看:367
本文介绍了无法通过angular8中的ngx-mqtt连接到MQTT代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无论我做什么,我都无法通过我的角度应用程序中的websocket连接到mqtt代理(在chrome和firefox中尝试). 为简单起见,我使用的是 HiveMQ经纪人,我已经发布了有关/gat/38/openReservationRequests一些数据

我已经关注了这个中篇文章关于如何使用ngx-mqtt以角度连接到mqtt,但对我来说却不起作用.

在我的应用中:

我已经安装了模块

npm install ngx-mqtt --save

我已经添加了配置,并在我的app.module.ts

中设置了模块forRoot.

...
export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
  connectOnCreate: true,
  hostname: 'broker.hivemq.com',
  port: 8000,
  path: '/gat/38/openReservationRequests',
  protocol: 'ws',
};

...
imports: [
    ...
    MqttModule.forRoot(MQTT_SERVICE_OPTIONS),
    ...
  ],
...

我正在app.component.tsngOnInit内执行此功能

...
import { IMqttMessage, MqttConnectionState, MqttService } from 'ngx-mqtt';
...

constructor(private mqttService: MqttService) {
    this.mqttService.state.subscribe((s: MqttConnectionState) => {
      const status = s === MqttConnectionState.CONNECTED ? 'CONNECTED' : 'DISCONNECTED';
      this.status.push(`Mqtt client connection status: ${status}`);
    });
  }

ngOnInit() {

    this.subscription = this.mqttService
                            .observe('/gat/38/openReservationRequests')
                            .subscribe((message: IMqttMessage) => {
                              this.msg = message;
                              console.log('msg: ', message);
                              console.log('Message: ' + message.payload.toString() + 'for topic: ' + message.topic);
                              console.log('subscribed to topic: ' + /gat/38/openReservationRequests);
                            });

}

但我总是收到此错误:

core.js:6014 ERROR TypeError: Cannot read property 'resubscribe' of undefined
    at MqttClient.subscribe (mqtt.min.js:1)
    at mqtt.service.js:211
    at Observable._subscribe (using.js:8)
    at Observable._trySubscribe (Observable.js:42)
    at Observable.subscribe (Observable.js:28)
    at FilterOperator.call (filter.js:13)
    at Observable.subscribe (Observable.js:23)
    at Observable.connect (ConnectableObservable.js:30)
    at RefCountOperator.call (refCount.js:17)
    at Observable.subscribe (Observable.js:23)

mqtt.min.js:1 WebSocket connection to 'ws://broker.hivemq.com:8000/gat/38/openReservationRequests' failed: Connection closed before receiving a handshake response

如果我在MQTT_SERVICE_OPTIONS中指定了clientId,我仍然会遇到相同的错误.

如果我将protocol更改为wss,则会收到其他错误:

core.js:6014 ERROR TypeError: Cannot read property 'resubscribe' of undefined
    at MqttClient.subscribe (mqtt.min.js:1)
    at mqtt.service.js:211
    at Observable._subscribe (using.js:8)
    at Observable._trySubscribe (Observable.js:42)
    at Observable.subscribe (Observable.js:28)
    at FilterOperator.call (filter.js:13)
    at Observable.subscribe (Observable.js:23)
    at Observable.connect (ConnectableObservable.js:30)
    at RefCountOperator.call (refCount.js:17)
    at Observable.subscribe (Observable.js:23)

mqtt.min.js:1 WebSocket connection to 'wss://broker.hivemq.com:8000/gat/38/openReservationRequests' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

如果我在观察主题之前尝试在app.component.ts ngOnInit内部手动连接:

this.mqttService.connect({
  hostname: 'broker.hivemq.com',
  port: 8000,
  path: '/gat/38/openReservationRequests',
  clientId: '34er23qwrfq42w3' //those are just random digits
});

我仍然收到上面的错误. 对我来说,最好连接一些内部组件(在用户经过身份验证后可以访问),因为我将拥有我的私有mqtt代理,并且该主题将取决于记录的用户信息.

我已经尝试了带有/不带有cliendId等的协议的任意组合,但是目前我还不知道这是怎么回事.我已经多次完全重新编译我的应用程序,我尝试将其发布在具有ssl证书但没有任何更改的测试服务器上.

已解决,感谢 @Anant Lalchandani 我设置了正确的路径.

另一个问题是'/mytopic'和'mytopic'确实是两个不同的主题,我也错误地使用了它. 这是我的代码,已更新: app.module.ts

export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
  connectOnCreate: false,
  hostname: 'broker.hivemq.com',
  port: 8000,
  path: '/mqtt'
};

appcomponent.ts(目前在ngOnInit内部)

 this.mqttService.connect({
      hostname: 'broker.hivemq.com',
      port: 8000,
      path: '/mqtt',
      clientId: '1234e3qer23rf'
    });

 this.mqttService.onConnect
        .subscribe(
          connack=> {
            console.log('CONNECTED');
            console.log(connack);
          }
        );

this.mqttService.observe('gat/38/openReservationRequests')
        .subscribe((message: IMqttMessage) => {
          this.msg = message;
          console.log(new TextDecoder('utf-8').decode(message.payload));
        });

解决方案

我已经检查过您共享的代码段.

在您的app.module.ts中,路径值应为'/mqtt'.您已在此处将主题设置为path的值.该主题只能被订阅/发布.当您在连接到Websocket时使用主题作为路径值时,您的应用程序将首先无法连接到websocket.

我们需要使用/mqtt作为路径的原因是,它指定您正在通过WebSocket协议发送MQTT消息.

HiveMQ本身的文档在其示例中声明将路径用作"/mqtt".您可以在此处中查看文档.

No matter what i do i can't connect to a mqtt broker via websocket in my angular application (trying in chrome and firefox). For simplicity i'm using HiveMQ broker, i've published on the topic /gat/38/openReservationRequests some data

I've followed this medium article on how to connect to mqtt in angular using ngx-mqtt but for me it is not working.

In my app:

I've installed the module

npm install ngx-mqtt --save

i've added the configuration and set the module forRoot in my app.module.ts

...
export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
  connectOnCreate: true,
  hostname: 'broker.hivemq.com',
  port: 8000,
  path: '/gat/38/openReservationRequests',
  protocol: 'ws',
};

...
imports: [
    ...
    MqttModule.forRoot(MQTT_SERVICE_OPTIONS),
    ...
  ],
...

i'm executing this function inside the ngOnInit of app.component.ts

...
import { IMqttMessage, MqttConnectionState, MqttService } from 'ngx-mqtt';
...

constructor(private mqttService: MqttService) {
    this.mqttService.state.subscribe((s: MqttConnectionState) => {
      const status = s === MqttConnectionState.CONNECTED ? 'CONNECTED' : 'DISCONNECTED';
      this.status.push(`Mqtt client connection status: ${status}`);
    });
  }

ngOnInit() {

    this.subscription = this.mqttService
                            .observe('/gat/38/openReservationRequests')
                            .subscribe((message: IMqttMessage) => {
                              this.msg = message;
                              console.log('msg: ', message);
                              console.log('Message: ' + message.payload.toString() + 'for topic: ' + message.topic);
                              console.log('subscribed to topic: ' + /gat/38/openReservationRequests);
                            });

}

but i am always getting this error:

core.js:6014 ERROR TypeError: Cannot read property 'resubscribe' of undefined
    at MqttClient.subscribe (mqtt.min.js:1)
    at mqtt.service.js:211
    at Observable._subscribe (using.js:8)
    at Observable._trySubscribe (Observable.js:42)
    at Observable.subscribe (Observable.js:28)
    at FilterOperator.call (filter.js:13)
    at Observable.subscribe (Observable.js:23)
    at Observable.connect (ConnectableObservable.js:30)
    at RefCountOperator.call (refCount.js:17)
    at Observable.subscribe (Observable.js:23)

mqtt.min.js:1 WebSocket connection to 'ws://broker.hivemq.com:8000/gat/38/openReservationRequests' failed: Connection closed before receiving a handshake response

if i specify the clientId inside the MQTT_SERVICE_OPTIONS i still get the same error.

if i change the protocol to wss i get a different error:

core.js:6014 ERROR TypeError: Cannot read property 'resubscribe' of undefined
    at MqttClient.subscribe (mqtt.min.js:1)
    at mqtt.service.js:211
    at Observable._subscribe (using.js:8)
    at Observable._trySubscribe (Observable.js:42)
    at Observable.subscribe (Observable.js:28)
    at FilterOperator.call (filter.js:13)
    at Observable.subscribe (Observable.js:23)
    at Observable.connect (ConnectableObservable.js:30)
    at RefCountOperator.call (refCount.js:17)
    at Observable.subscribe (Observable.js:23)

mqtt.min.js:1 WebSocket connection to 'wss://broker.hivemq.com:8000/gat/38/openReservationRequests' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

If i try to connect manually inside my app.component.ts ngOnInit before observing the topic:

this.mqttService.connect({
  hostname: 'broker.hivemq.com',
  port: 8000,
  path: '/gat/38/openReservationRequests',
  clientId: '34er23qwrfq42w3' //those are just random digits
});

i still get the error above. For me it would be ideal to connect in some inner component (accessible after the user is authenticated) because i will have my private mqtt broker and the topic will depend on the logged user information.

I've tried any combination of protocol with/without cliendId etc but at this point i don't know what is wrong. I've already fully recompiled my app lots of times, i've tried publishing it on my test-server which has a ssl certificate but nothing changed.

Resolved thanks to @Anant Lalchandani i set the correct path.

The other problem was that '/mytopic' and 'mytopic' are indeed two different topic and i was using it wrong too. This is my code, updated: app.module.ts

export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
  connectOnCreate: false,
  hostname: 'broker.hivemq.com',
  port: 8000,
  path: '/mqtt'
};

appcomponent.ts (inside ngOnInit for now)

 this.mqttService.connect({
      hostname: 'broker.hivemq.com',
      port: 8000,
      path: '/mqtt',
      clientId: '1234e3qer23rf'
    });

 this.mqttService.onConnect
        .subscribe(
          connack=> {
            console.log('CONNECTED');
            console.log(connack);
          }
        );

this.mqttService.observe('gat/38/openReservationRequests')
        .subscribe((message: IMqttMessage) => {
          this.msg = message;
          console.log(new TextDecoder('utf-8').decode(message.payload));
        });

解决方案

I have checked the code snippets you shared in question.

In your app.module.ts, the path value should be '/mqtt'. You have set the topic as the value of path here. The topic can only be subscribed/published. As you are using a topic as a path value at the time of connecting to a websocket, your application will not be able to connect to websocket at the first place.

The reason why we need to use /mqtt as a path is it specifies you are sending MQTT messages over the WebSocket protocol.

The documentation of HiveMQ itself stated to use the path as '/mqtt' in its example. You can check the documentation here.

这篇关于无法通过angular8中的ngx-mqtt连接到MQTT代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆