I've made an Ionic PWA mqtt that publishes via a websocket, but when I deploy the app (I'm using AWS), it only works in Google Chrome, if I test it in an Incognito window, it doesn't work.
In the console it show this error on all devices (pc/mobile) that aren't working:
bSocket connection to 'ws://test.mosquitto.org:8081/' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
Below is my javascript Ionic code
import { Component } from '#angular/core';
import { MQTTService } from 'ionic-mqtt';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
private _mqttClient: any;
temp = 19;
private MQTT_CONFIG: {
host: string,
port: number,
clientId: string,
path: string,
} = {
host: "test.mosquitto.org",
port: 8081,
clientId: "qeekljeqe" + Math.floor(Math.random()*100),
path: "/",
};
private TOPIC: string[] = [];
constructor(private _mqttService: MQTTService) {
}
ngOnInit() {
this._mqttClient = this._mqttService.loadingMqtt(this._onConnectionLost, this._onMessageArrived, this.TOPIC, this.MQTT_CONFIG);
}
private _onConnectionLost(responseObject) {
// connection listener
// ...do actions when connection lost
console.log('_onConnectionLost', responseObject);
}
private _onMessageArrived(message) {
// message listener
// ...do actions with arriving message
console.log('message', message);
}
public publishMessage(TOPICO : string, VALOR : string) {
console.log('publishMessage')
this._mqttService.publishMessage(TOPICO, VALOR);
}
Related
I'm trying to connect to a Socket from my angular Application on the ngOnInit method.
Here is how my Service Looks Like
import { Injectable } from '#angular/core';
import {webSocket, WebSocketSubject} from 'rxjs/webSocket';
import { map } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class SocketService {
private socket$!: WebSocketSubject<any>;
constructor() {
// Connect to the local websocket server on port 15001. Handle any Exceptions.
try {
this.socket$ = webSocket('ws://localhost:15001');
}
catch (e) {
console.log(e);
}
}
// Receive messages from the server
public receive(){
return this.socket$.pipe(
map(message=>JSON.parse(message))
)
}
}
Here is My Component.ts
import { Component, OnInit } from '#angular/core';
import { SocketService } from './services/socket.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private socketService: SocketService) { }
ngOnInit() {
try{
this.socketService.receive().subscribe((data) => {
console.log(data);
});
}
catch (e) {
console.log(e);
}
}
title = 'MarketFeed';
}
Despite adding a try-catch I'm getting this error which is difficult to debug.
Here is the Error Message on the console
WebSocket connection to 'ws://localhost:15001/' failed:
ngOnInit # app.component.ts:15 Show 37 more frames app.component.ts:15
ERROR Event {isTrusted: true, type: 'error', target: WebSocket,
currentTarget: WebSocket, eventPhase: 0, …} Zone -
WebSocket.addEventListener:error (async)
ngOnInit # app.component.ts:15 Promise.then (async) 4431 # main.ts:6
webpack_exec # main.ts:7 (anonymous) # main.ts:7 (anonymous) # main.ts:7 (anonymous) # main.js:2 Show 134 more frames
Blockquote
What could I be missing? I'm able to consume the same socket using node js. But here on Angular, it is not working.
This is in an Angular 7 project and the code was written maybe 5-6 years ago, and I'm trying to update the application to latest Angular. Right now I'm just testing the login portion of the app which is basic http authentication. This is the last piece I need to refactor but im pretty lost. I don't want to break the entire system or do a full revamp just get something working so the whole ui can be upgraded from angular 7 to 14.
This is the old code below.
import { ConnectionBackend, Http, Request, RequestOptions, RequestOptionsArgs, Response, XHRBackend } from '#angular/http';
import { AuthService } from './../auth/auth.service';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
#Injectable()
export class AuthHttp extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions, private auth : AuthService) {
super(backend, defaultOptions);
this.auth = auth;
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
// hack to deal with compatibility issue of rxjs versions
// see https://stackoverflow.com/questions/38168581/observablet-is-not-a-class-derived-from-observablet
let optionsAny = <any>options;
let opts: RequestOptionsArgs = {
method: optionsAny.method,
body: optionsAny.body,
withCredentials: true,
headers: optionsAny.headers,
}
let query = '';
for (let k of Array.from(optionsAny.params.paramsMap.keys())) {
let v = optionsAny.params.paramsMap.get(k);
query += '&' + k + '=' + encodeURIComponent(v);
}
if (query) {
url = url + '?' + query.substring(1);
}
return Observable.create(sub => {
super.request(url, opts).subscribe(
res => { sub.next(res); },
err => {
if (err.status === 401) {
this.auth.signout();
} else {
sub.error(err);
}
} );
});
}
}
I tried some stuff but it all seems to lead to no where. I'm not really sure where to start. This is my first time using angular and it's a decently sized project. I feel like there's a really simple way to do this, but I'm not totally sure, I've been researching and haven't found anyone quite doing anything like this.
It compiles with no errors with an empty class. Like below, these imports are all the equivalent or roughly equivalent for the new angular httpclientmodule I believe .
import { AuthService } from './../auth/auth.service';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpParams, HttpHeaders, HttpXhrBackend, HttpResponse, HttpBackend, HttpRequest, HttpEvent } from '#angular/common/http';
#Injectable()
export class AuthHttp extends HttpClient {}
Then I get 2 errors below in the console of my browser when i do ng serve with the blank class above.
ERROR NullInjectorError: R3InjectorError(AppModule)[ApiService -> ApiService -> ApiService]:
NullInjectorError: No provider for ApiService!
Angular 9
AppComponent_Factory app.component.ts:11
Angular 26
631 main.ts:11
Webpack 7
core.mjs:6362:22
Angular 16
Any help on where to start or helpful resource is appreciated thank you.
This is how ApiService is implemented
#Injectable()
export class ApiService {
private apiUrl: string;
constructor(private authHttp: AuthHttp, private auth: AuthService) {}
getUrl() {
return this.apiUrl;
}
setUrl(url: string) {
this.apiUrl = url;
}
getConfiguration(): Configuration {
const token = this.auth.getToken();
return new Configuration({
accessToken: token
});
}
getUserApi(): UserService {
return new UserService(this.authHttp, this.apiUrl, this.getConfiguration());
}
getProductionApi(): ProductionService {
return new ProductionService(
this.authHttp,
this.apiUrl,
this.getConfiguration()
);
}
Without seeing the implementation of ApiService and its difficult to identify the issue. Broadly speaking it seems to me like the ApiService isn't provided from any module.
A quick check would be to provide it to the root of the application.
#Injectable({
providedIn: 'root',
})
export class ApiService ....
Ok I got it working but I'm still not totally sure how it's working or what it's doing. Basically the old method was doing this in a complicated why because of the limitations of older angular 2.
#Injectable()
export class AuthHttp extends HttpClient implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authReq = req.clone({
withCredentials: true
});
return next.handle(authReq);
}
}
I found source code for rss data on my page in angular.
https://stackblitz.com/edit/angular-8-rss-feed
But it works only for example
adress("https://gadgets.ndtv.com/rss/feeds"). Please help.
Console chrome logs
Access to XMLHttpRequest at 'https://news.yahoo.com/rss/' (redirected
from 'http://news.yahoo.com/rss/') from origin 'null' has been blocked
by CORS policy: No 'Access-Control-Allow-Origin' header is present on
the requested resource.
core.js:6014 ERROR HttpErrorResponse {headers: HttpHeaders, status: 0,
statusText: "Unknown Error", url: "http://news.yahoo.com/rss/", ok:
false, …} Why the code doesn't work with other rss feeds?.What change?
app.component.ts
import { Component } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import * as xml2js from "xml2js";
import { NewsRss } from './news-rss';
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
RssData: NewsRss;
constructor(private http: HttpClient) {}
GetRssFeedData() {
const requestOptions: Object = {
observe: "body",
responseType: "text"
};
this.http
.get<any>("https://gadgets.ndtv.com/rss/feeds", requestOptions)
.subscribe(data => {
let parseString = xml2js.parseString;
parseString(data, (err, result: NewsRss) => {
this.RssData = result;
});
});
}
}
export interface IRssData {}
news-rss.ts
export interface NewsRss {
rss: IRssObject;
}
export interface IRssObject {
$: any;
channel: Array<IRssChannel>;
}
export interface IRssChannel {
"atom:link": Array<string>;
description: Array<string>;
image: Array<IRssImage>;
item: Array<IRssItem>;
language: Array<string>;
lastBuildDate: Date;
link: Array<string>;
title: Array<string>;
}
export interface IRssImage {
link: Array<string>;
title: Array<string>;
url: Array<string>;
}
export interface IRssItem {
category: Array<string>;
description: Array<string>;
guid: any;
link: Array<string>;
pubDate: Date;
title: Array<string>;
}
Other details angular8, vscode as editor, server start with ng serve
seems like you have a CORS Problem.
You can just try to use a CORS extension in your browser and the extension will add the right headers to the responses for you. Here for example, you can find one Chrome extension CORS Plugin Chrome
see this Answer too:
How to use a CORS proxy to get around “No Access-Control-Allow-Origin header” problems
I was assigned the task of making a dynamic load of settings for the Angular application from the JSON file on the server during the application start. The peculiarity is that the application uses server rendering with Universal.
I tried to do this for the browser using this method.
https://juristr.com/blog/2018/01/ng-app-runtime-config
But it works only for the browser app rendering.
How to do it for server-side rendering?
The most likely culprit here is that you're loading json file from relative path but
Universal does not currently support relative urls but only absolute.
So you can provide absolute path to your json file:
server.ts
app.engine('html', (_, options, callback) => {
const protocol = options.req.protocol;
const host = options.req.get('host');
const engine = ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP),
{ provide: 'APP_BASE_URL', useFactory: () => `${protocol}://${host}`, deps: [] },
]
});
engine(_, options, callback);
});
your.service.ts
#Injectable()
export class ConfigProvider {
config: Config;
constructor(
private http: HttpClient,
#Inject(PLATFORM_ID) private platformId: {},
#Inject('APP_BASE_URL') #Optional() private readonly baseUrl: string
) {
if (isPlatformBrowser(platformId)) {
this.baseUrl = document.location.origin;
}
}
loadConfig() {
return this.http.get<Config>(
`${this.baseUrl}/assets/plugins-config.json`
);
}
}
For more details see example of project that also uses APP_INITIALIZER to load config
You could use the following package
https://www.npmjs.com/package/runtime-config-loader
This is what I use and works just fine...
constructor(#Inject(DOCUMENT) private document: Document,
#Inject(PLATFORM_ID) private platformId: Object,
#Optional() #Inject(REQUEST) private request: any) {
if (isPlatformServer(platformId)) {
const port = request.socket.localPort;
this.baseUrl = this.request.protocol + '://' + this.request.hostname + ':' + port;
} else {
this.baseUrl = this.document.location.origin;
}
....
}
I need to use publish Subscribe methods in my Ionic 3 application.
I followed this page.
Is there any way we can link MQTT with our Ionic 3 application? If yes, how so?
How exactly do I need to go about it for a successful connection?
I installed ng2-mqtt service using
npm install ng2-mqtt --save
This is my code:
index.html
<script src="cordova.js"></script>
<script src="node_modules/ng2-mqtt/mqttws31.js" type="text/javascript"></script>
home.ts
import {Paho} from 'mqttws31'
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private _client: Paho.MQTT.Client;
constructor(public paho: Paho) {
}
this._client = new Paho.MQTT.Client("52.66.30.178", 1883, "path", "someclient_id");
this._client.onConnectionLost = (responseObject: Object) => {
console.log('Connection lost.');
this.getServerMessage();
this._client.onMessageArrived = (message: Paho.MQTT.Message) => {
console.log('Message arrived.');
};
this._client.connect({ onSuccess: this.onConnected.bind(this); });
}
Still I can't get it to work.
Any suggestions and changes will help me. I'm stuck please do.
After searching and trying out different things for a while, I found this solution, you can use this library if you want to use MQTT in your project.
Install it using npm install ngx-mqtt --save
Usage: app.module.ts
import { Observable } from 'rxjs/Observable';
import {
IMqttMessage,
MqttModule,
MqttService
} from 'ngx-mqtt';
export const MQTT_SERVICE_OPTIONS = {
hostname: '13.127.53.13',
port: 9001,
path: '/mqtt'
};
export function mqttServiceFactory() {
return new MqttService(MQTT_SERVICE_OPTIONS);
}
#NgModule({
imports: [
BrowserModule,
HttpModule,
MqttModule.forRoot({
provide: MqttService,
useFactory: mqttServiceFactory
}),
IonicModule.forRoot(MyApp)
]
And then you can use it in your page like: (ex: home.ts file)
import { IMqttMessage, MqttModule, MqttService } from 'ngx-mqtt';
import { Observable } from 'rxjs/Observable';
export class HomePage {
constructor( private _mqttService: MqttService)
{
this._mqttService.observe('home/door').subscribe((message: MqttMessage) =>
{
this.sensor1 = message.payload.toString();
console.log(this.sensor1);
});
}
publishMessage()
{
this._mqttService.unsafePublish("home/button", "on", {qos: 0, retain: false});
}
For more information about this library: https://github.com/sclausen/ngx-mqtt