| @@ -96,6 +96,58 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| ngx-toastr | |||
| MIT | |||
| The MIT License (MIT) | |||
| Copyright (c) Scott Cooper <[email protected]> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| of this software and associated documentation files (the "Software"), to deal | |||
| in the Software without restriction, including without limitation the rights | |||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
| copies of the Software, and to permit persons to whom the Software is | |||
| furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in all | |||
| copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| SOFTWARE. | |||
| rtsp-relay | |||
| MIT | |||
| MIT License | |||
| Copyright (c) 2018-2021 Kyle Hensel | |||
| All rights reserved. | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| of this software and associated documentation files (the "Software"), to deal | |||
| in the Software without restriction, including without limitation the rights | |||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
| copies of the Software, and to permit persons to whom the Software is | |||
| furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in all | |||
| copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| SOFTWARE. | |||
| rxjs | |||
| Apache-2.0 | |||
| Apache License | |||
| @@ -29,6 +29,7 @@ | |||
| "express-ws": "^5.0.2", | |||
| "leaflet": "^1.9.4", | |||
| "leaflet.markercluster": "^1.5.3", | |||
| "ngx-mqtt": "^17.0.0", | |||
| "ngx-toastr": "^17.0.2", | |||
| "rtsp-relay": "^1.8.0", | |||
| "rxjs": "~7.8.0", | |||
| @@ -7,8 +7,18 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; | |||
| import {SharedModule} from "./shared/shared.module"; | |||
| import {HttpClientModule} from "@angular/common/http"; | |||
| import { ToastrModule } from 'ngx-toastr'; | |||
| import { IMqttServiceOptions, MqttModule } from 'ngx-mqtt'; | |||
| export const connection: IMqttServiceOptions = { | |||
| hostname: 'test.mosquitto.org', | |||
| port: 1883, | |||
| clean: true, // 保留会话 | |||
| connectTimeout: 4000, // 超时时间 | |||
| reconnectPeriod: 4000, // 重连时间间隔 | |||
| // 认证信息 | |||
| clientId: 'pm-1720539453210', | |||
| protocol: 'ws', | |||
| connectOnCreate: false, | |||
| } | |||
| @NgModule({ | |||
| @@ -26,6 +36,7 @@ import { ToastrModule } from 'ngx-toastr'; | |||
| preventDuplicates: true, | |||
| autoDismiss: true | |||
| }), // ToastrModule added | |||
| MqttModule.forRoot(connection) | |||
| ], | |||
| providers: [], | |||
| bootstrap: [AppComponent] | |||
| @@ -0,0 +1,108 @@ | |||
| import { Injectable } from '@angular/core'; | |||
| import { webSocket, WebSocketSubject } from 'rxjs/webSocket'; | |||
| import { BehaviorSubject,Subject } from "rxjs"; | |||
| import { config } from "../../../assets/config/config"; | |||
| import { | |||
| IMqttMessage, | |||
| IMqttServiceOptions, | |||
| MqttService, | |||
| IPublishOptions, | |||
| } from 'ngx-mqtt'; | |||
| import { IClientSubscribeOptions } from 'mqtt-browser'; | |||
| import { Subscription } from 'rxjs'; | |||
| @Injectable({ | |||
| providedIn: 'root' | |||
| }) | |||
| export class MqttClientService { | |||
| client: MqttService | undefined; | |||
| constructor(private _mqttService: MqttService) { | |||
| this.client = this._mqttService; | |||
| } | |||
| private curSubscription: Subscription | undefined; | |||
| connection = { | |||
| hostname: 'test.mosquitto.org', | |||
| clean: true, // 保留会话 | |||
| path:'/mqtt', | |||
| port: 8081, | |||
| connectTimeout: 4000, // 超时时间 | |||
| reconnectPeriod: 4000, // 重连时间间隔 | |||
| // 认证信息 | |||
| protocol: 'wss', | |||
| } | |||
| subscription = { | |||
| topic: 'isoft/log10', | |||
| qos: 0, | |||
| }; | |||
| publish = { | |||
| topic: 'isoft/in10', | |||
| qos: 0, | |||
| payload: '{ "msg": "Hello, I am browser." }', | |||
| }; | |||
| receiveNews = ''; | |||
| qosList = [ | |||
| { label: 0, value: 0 }, | |||
| { label: 1, value: 1 }, | |||
| { label: 2, value: 2 }, | |||
| ]; | |||
| isConnection = false; | |||
| subscribeSuccess = false; | |||
| // 创建连接 | |||
| createConnection() { | |||
| // 连接字符串, 通过协议指定使用的连接方式 | |||
| // ws 未加密 WebSocket 连接 | |||
| // wss 加密 WebSocket 连接 | |||
| // mqtt 未加密 TCP 连接 | |||
| // mqtts 加密 TCP 连接 | |||
| // wxs 微信小程序连接 | |||
| // alis 支付宝小程序连接 | |||
| try { | |||
| this.client?.connect(this.connection as IMqttServiceOptions) | |||
| } catch (error) { | |||
| console.log('mqtt.connect error', error); | |||
| } | |||
| this.client?.onConnect.subscribe(() => { | |||
| this.isConnection = true | |||
| console.log('Connection succeeded!'); | |||
| }); | |||
| this.client?.onError.subscribe((error: any) => { | |||
| this.isConnection = false | |||
| console.log('Connection failed', error); | |||
| }); | |||
| this.client?.onMessage.subscribe((packet: any) => { | |||
| this.receiveNews = this.receiveNews.concat(packet.payload.toString()) | |||
| console.log(`Received message ${packet.payload.toString()} from topic ${packet.topic}`) | |||
| }) | |||
| } | |||
| // 订阅主题 | |||
| doSubscribe() { | |||
| const { topic, qos } = this.subscription | |||
| this.curSubscription = this.client?.observe(topic, { qos } as IClientSubscribeOptions).subscribe((message: IMqttMessage) => { | |||
| this.subscribeSuccess = true | |||
| console.log('Subscribe to topics res', message.payload.toString()) | |||
| }) | |||
| } | |||
| // 取消订阅 | |||
| doUnSubscribe() { | |||
| this.curSubscription?.unsubscribe() | |||
| this.subscribeSuccess = false | |||
| } | |||
| // 发送消息 | |||
| doPublish() { | |||
| const { topic, qos, payload } = this.publish | |||
| console.log(this.publish) | |||
| this.client?.unsafePublish(topic, payload, {qos} as IPublishOptions) | |||
| } | |||
| // 断开连接 | |||
| destroyConnection() { | |||
| try { | |||
| this.client?.disconnect(true) | |||
| this.isConnection = false | |||
| console.log('Successfully disconnected!') | |||
| } catch (error: any) { | |||
| console.log('Disconnect failed', error.toString()) | |||
| } | |||
| } | |||
| } | |||