With WebsocketSubject wrapping native WebSocket object the only way of turning off connection from browser is calling an unsubscribe method. It would be nice to make native close method accessible so we could manually set code and reason while closing the connection
Is your feature request related to a problem? Please describe.
We're seeing issue when we call unsubscribe since the event passed to closeObserver looks like this
_wasClean: false, code: 1006_ in Chrome while in Firefox _wasClean: true, code: 1005_
Describe the solution you'd like
A new method to pass code and reason to websocket close method same way native WebSocket object supports
This is already possible, 馃槃. When creating the webSocketSubject we are allow to pass a plain object (a.k.a webSocketSubjectConfig) that we can use to set code and reason while closing the connection. From docs.
import { webSocket } from "rxjs/webSocket";
const webSocketSubjectConfig = {
closeObserver: {
next(closeEvent) {
const customError = { code: 6666, reason: "Custom reason message" }
console.log(`code: ${customError.code}, reason: ${customError.reason}`);
}
}
};
const wsSubject = webSocket(webSocketSubjectConfig);
This is already possible, 馃槃. When creating the
webSocketSubjectwe are allow to pass a plain object (a.k.awebSocketSubjectConfig) that we can use to set code and reason while closing the connection. From docs.import { webSocket } from "rxjs/webSocket"; const webSocketSubjectConfig = { closeObserver: { next(closeEvent) { const customError = { code: 6666, reason: "Custom reason message" } console.log(`code: ${customError.code}, reason: ${customError.reason}`); } } }; const wsSubject = webSocket(webSocketSubjectConfig);
This only creates a new error object inside the closeObserver but this does not set the native CloseEvent.
Instead, we need a method like complete({ code: 6666, reason: "Custom reason message" }) or unsubscribe({ code: 6666, reason: "Custom reason message" }) to pass the closing code and reason to the native one.
Any update? The lack of this feature makes us not to upgrade Rxjs6 as we can access the primitive web socket in Rxjs5 such that we can call the close method manually.
If we cannot close with code and reason, is it possible to expose the primitive web socket in Rxjs6?
@jackyyuenahsay what do you mean by, but this does not set the native CloseEvent?.
Since CloseEvent.code and CloseEvent.reason are read-only properties (check more on this).
Please share how would you do it with the native Websocket API.
@luillyfe when I was creating this feature request. I had in mind this https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close
Where I believe when by using native WebSocket you can manually close and define your own code and reason
Or am I mistaken?
@luillyfe @Fruko is right. WebSocket provides a close method which allows us to close the socket with our own code and reason such that these info will pass in CloseEvent. As the RxJS 6 WebSocketSubject does not expose the primitive socket instance, we have no way to call the close method.
@Fruko is right, WebSocket does provide a close method. Now, @Fruko @jackyyuenahsay let me ask, how having access to the close method of WebSocket API makes it more valuable than using closeObserver.
@luillyfe I can't speak for @jackyyuenahsay, but in our use-case we don't really need native access to WebSocket.close method, we just want a method that is going to close the connection with given CloseEvent.code and CloseEvent.reason
@luillyfe, if you can provide a method to us for closing the connection with given CloseEvent.code and CloseEvent.reason, then we don't need to have the native access to the close method.
The way you do it in Rxjs is as the follows, you call the unsubscribe method (this will close the connection), and but right before doing that, it will invoke the closeObserver method from Rxjs. In closeObserver you can put any logic you want (raise an error, print a message to the console). But as far I understand you still want to modify the CloseEvent raised when closing the connection. To be honest I do not see any benefit from this.
As a workaround, you can access the Native Websocket (but please don't do it):
import { webSocket } from "rxjs/webSocket";
const webSocketSubjectConfig = {
closeObserver: {
next(closeEvent) {
// Websocket instance
console.log(closeEvent.target);
}
}
};
const wsSubject = webSocket(webSocketSubjectConfig);
Here is our use case of using the close method with CloseEvent.code and CloseEvent.reason:
Our app has different reasons and areas to close the web socket, some might need auto reconnect while some does not. So when we close the web socket(may be unwillingly due to server issue or connection issue), we will provide a reason and code to the close method.
In the close Observer, we will check the reason and code to determine if auto-reconnect is needed.
As you can see, this cannot be done in the closeObserver as it is a centralized area which does not know anything about the closing reason and code. We need to know why the socket is closed inside the closeObserver. The unsubscribe/close() method caller is the only person who know the reason and code.
Any news here? or just any other approach found?
Thanks
any news here ?
can rx.js implements this.ws.close(reasonCode) ? or better way for resolve it ?
Sorry I was so late to answering this one..
There's always been a way to do this:
// This will close the underlying websocket with a reason.
webSocketSubject.error({ code: 3000, reason: 'Some custom reason' });
We clearly need to update the documentation.
cc @JWO719
Most helpful comment
This only creates a new error object inside the closeObserver but this does not set the native CloseEvent.
Instead, we need a method like complete({ code: 6666, reason: "Custom reason message" }) or unsubscribe({ code: 6666, reason: "Custom reason message" }) to pass the closing code and reason to the native one.