I'm working on a project which requires the use of a websocket so the server can rapidly push data to the web UI. I'm using Angular v5 with angular-cli. However I'm having a hard time getting the websocket connection to retry when it fails.
For those interested my project in its current state can be found here.
I followed this tutorial but haven't really been able to get to grips with the rxjs principles. I've been doing a lot of trial and error get where I am now.
So I created a websocket service which sets up the Observable
:
export class WebsocketService {
constructor() { }
private subject: Rx.Subject<MessageEvent>;
public connect(url): Rx.Subject<MessageEvent> {
if (!this.subject) {
this.subject = this.create(url);
}
return this.subject;
}
private create(url): Rx.Subject<MessageEvent> {
let ws = new WebSocket(url);
let observable = Rx.Observable.create(
(obs: Rx.Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = obs.complete.bind(obs);
return ws.close.bind(ws);
})
let observer = {
next: (data: Object) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data));
}
}
}
return Rx.Subject.create(observer, observable);
}
}
And then the RaceDataService
which uses the WebSocketService
to map the data to something useful:
export class RaceDataService {
public dataStream: Subject<any>;
constructor(wsService: WebsocketService) {
this.dataStream = <Subject<any>>wsService
.connect(ETS_URL)
.map((response:any): any => {
let data = JSON.parse(response.data);
return data
})
.retry(3)
}
sendAction(action:WebsocketAction) {
this.dataStream.next(action);
}
}
Finally I subscribe to the observable in my race-display
component like this:
constructor(private raceDataService:RaceDataService) {
raceDataService.dataStream.subscribe(
msg => {
console.log("Response from websocket: ");
console.log(msg);
if(msg.RaceData) {
this.HandleCurrentRaceData(msg.RaceData);
}
},
err => {
this.isConnected = false;
},
() => {
this.sessionEnded = true;
}
)
}
Now from what I've read, putting the .retry(3)
after the setting up the observable object should ensure the connection is retried 3 times after failing. Eventually this will not be enough and I'll have to use retryWhen()
to do some more advanced stuff, but at this point this simple retry isn't even working, the websocket connection is just attempted one time and thats it.
I'd be really grateful for any pointers.