Why closing websocket connection in Chrome by javascript is not immediately? - javascript

I tried to use rxjs webSocket to connect server. When I use .complete() function, the closingObserver is triggered immediately. But I received CloseEvent is almost 1 minute later.
So, how can I get the CloseEvent immediately?
Here is an example.
class SomeService {
private wsSource$ = webSocket({
url: "ws://xxxxxx.com/api/v1/xxx",
openObserver: this.openObserver,
closingObserver: this.closingObserver,
});
connect() {
this.wsSource$.subscribe({
next: (e) => console.log(e),
error: (err) => console.log(err),
complete: () => console.log("complete!!!")
});
}
disconnect() {
this.wsSource$.complete();
}
}
After connect(), Chrome will log the CloseEvent after almost 1 minute.
It is not logged by observer complete function, it is logged by error function.

Related

Cypress intercept not matching url

I am fetching data with a network call:
https://mydomain.xxx/third-party-service/pragma?perPage=15&page=1
Request Method: GET
Trying to intercept it with code:
// Overriden not to clear localStorage authentication tokens
const clear = Cypress.LocalStorage.clear;
Cypress.LocalStorage.clear = function(keys) {
if (keys) {
return;
}
};
context('Navigation', () => {
before(() => {
cy.login();
cy.visit('/');
});
beforeEach(() => {
cy.get('[data-test=test-burger]').click();
});
it('Tests table', () => {
cy.get('[data-test=invoices]').click();
cy.intercept('**/pragma**').as('getPragmaDocuments');
cy.wait('#getPragmaDocuments');
//....assertions here after API call is waited
});
});
However, it does not intercept the network request.
Error I get:
Timed out retrying after 5000ms: cy.wait() timed out waiting 5000ms for the 1st request to the route: getPragmaDocuments. No request ever occurred.Learn more
I see your problem, and I'm not sure why your "fix" worked, haha.
You need to start the cy.intercept() before the click, like this:
cy.intercept('**/pragma**').as('getPragmaDocuments');
cy.get('[data-test=invoices]').click();
cy.wait('#getPragmaDocuments');

Why does socket.io-client not connect inside of an RXJS subscription?

I am trying to initiate a socket.io connection upon receiving a certain event in an rxjs observable. The socket.io connection starts fine inside startEventStream if it's outside of the subscribe, but when placed in the subscribe, even though the event is firing, the callback inside socket is never called.
function startEventStream(
stateLoaded$: Observable<LoginEvent>
): Observable<AoEvent> {
const socket = require('socket.io-client')('http://localhost:8003')
const ret = new Subject<AoEvent>()
const merged = merge(stateLoaded$, ret)
const session = '895e17a0-6c2b-11ea-8d86-45f581e4b250'
const token =
'f3ccdd81c2ece391891cba4f7d4eb8466d3d44675dd70f11e21190ae13dfdf69'
merged.subscribe({
next(val) {
process.nextTick(() => {
if (val.type == 'state-loaded') {
console.log('we should be connecting') // this prints
socket.on('connect', function() {
console.log('connected') // this doesn't print
ret.next({ type: 'socket-connected' })
socket.emit('authentication', {
session,
token
})
})
}
})
}
})
return ret
}
I got it working by passing { autoconnect: false } into the initialization of the socket and doing socket.on() inside of the subscribe. I think the connect event was getting discarded before the subscription function was called, and so the callback was never firing. Starting the connection inside solves the problem.

Asp.net signalR onclose is getting called only once

I'm using asp.net signalr in my application. I'm doing manual reconnect. It's reconnecting first time when it's disconnected. I'm using onclose method to reconnect. But the onclose event is not getting called second time.
Below is my code.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/connectHub")
.configureLogging(signalR.LogLevel.Information)
.build();
async function start() {
try {
await connection.start();
console.log("connected");
} catch (err) {
console.log(err);
setTimeout(() => start(), 5000);
}
};
connection.onclose(async () => {
await start();
});
The method "onclose" is calling when it's disconnected first time. When it disconnects second time it's not coming to "onclose" method, so reconnect also not happening.
Thanks

MQTT.js - How to handle connection errors?

I have difficulties detecting connection errors with MQTT.js.
I'm trying to use it in an Angular service and connecting and communicating with the server seems to work fine when the server is running but client.on('error', ...) never fires.
I managed to detect errors when connecting by attaching the error callback to client.stream instead, but stream seems to be a private property since it isn't exposed in the official TypeScript definitions, so not sure if this really is the correct way to go.
But what I still don't get to work are errors when the connection is lost, none of the error handlers fire. Instead the browser console logs unhandled websocket errors.
Sample code:
import { Injectable } from '#angular/core';
import { connect, MqttClient } from 'mqtt';
import * as msgpack5 from 'msgpack5';
import { environment } from '../../environments/environment';
#Injectable()
export class MqttService {
private client: MqttClient;
private msgpack: msgpack5.MessagePack;
constructor() {
this.msgpack = msgpack5();
this.client = connect(`ws://${environment.host}:8001/mqtt`);
this.client.on('connect', () => {
console.log('connected');
this.client.subscribe('foo');
});
this.client['stream'].on('error', (error) => {
// fires when connection can't be established
// but not when an established connection is lost
console.log('stream', error);
this.client.end();
});
this.client.on('error', (error) => {
console.log('client', error); // never fires
});
this.client.on('message', (topic, payload) => {
console.log(topic, this.msgpack.decode(payload));
});
}
}
I had a very similar issue with client.on('error'.. didnt trigger on WebSocket connection error, the solution was:
client.stream.on('error', (err) => {
console.log('error', err);
client.end()
});

Observable Finally on Subscribe

According to this artcle, onComplete and onError function of the subscribe are mutually exclusive.
Meaning either onError or onComplete events will fire up in my subscribe.
I have a logic block which needs to be executed whether I receive an error, or I finish my steam of information successfully.
I looked up for something like finally in python, but all I found is finally which needs to be attached to the observable I create.
But I want to to do that logic only when I subscribe, and after the stream has ended, whether successfully or with an error.
Any ideas?
The current "pipable" variant of this operator is called finalize() (since RxJS 6). The older and now deprecated "patch" operator was called finally() (until RxJS 5.5).
I think finalize() operator is actually correct. You say:
do that logic only when I subscribe, and after the stream has ended
which is not a problem I think. You can have a single source and use finalize() before subscribing to it if you want. This way you're not required to always use finalize():
let source = new Observable(observer => {
observer.next(1);
observer.error('error message');
observer.next(3);
observer.complete();
}).pipe(
publish(),
);
source.pipe(
finalize(() => console.log('Finally callback')),
).subscribe(
value => console.log('#1 Next:', value),
error => console.log('#1 Error:', error),
() => console.log('#1 Complete')
);
source.subscribe(
value => console.log('#2 Next:', value),
error => console.log('#2 Error:', error),
() => console.log('#2 Complete')
);
source.connect();
This prints to console:
#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message
Jan 2019: Updated for RxJS 6
The only thing which worked for me is this
fetchData()
.subscribe(
(data) => {
//Called when success
},
(error) => {
//Called when error
}
).add(() => {
//Called when operation is complete (both success and error)
});
I'm now using RxJS 5.5.7 in an Angular application and using finalize operator has a weird behavior for my use case since is fired before success or error callbacks.
Simple example:
// Simulate an AJAX callback...
of(null)
.pipe(
delay(2000),
finalize(() => {
// Do some work after complete...
console.log('Finalize method executed before "Data available" (or error thrown)');
})
)
.subscribe(
response => {
console.log('Data available.');
},
err => {
console.error(err);
}
);
I have had to use the add medhod in the subscription to accomplish what I want. Basically a finally callback after the success or error callbacks are done. Like a try..catch..finally block or Promise.finally method.
Simple example:
// Simulate an AJAX callback...
of(null)
.pipe(
delay(2000)
)
.subscribe(
response => {
console.log('Data available.');
},
err => {
console.error(err);
}
)
.add(() => {
// Do some work after complete...
console.log('At this point the success or error callbacks has been completed.');
});

Categories