Reputation: 821
I'm trying to make a very simple websocket service in Angular 12 but I can't seem to find any working examples. I have tried a number of tutorials including this more recent one, but even the example they give does not seem to be working for me (I have tried to implement it on my own, and have also tried to git clone their example. Neither have worked)
I am trying to learn Angular 12 by porting an old AngularJS app in which I used websockets and the ng-websocket package. RxJS seems to one of the more popular libraries used for websockets so I went with that. So far I have only been able to get the following example working:
// app.component.ts
import { webSocket } from 'rxjs/webSocket';
import {environment} from '../environments/environment';
...
const subject = webSocket(environment.backendWebsocketEndpoint)
subject.subscribe(msg => {
console.log('Message from server?', msg)
},
err => {
console.log('Error with websocket connection:', err)
},
() => {
console.log('complete')
}
)
subject.next('my message');
How can I turn this simple example into a service that I can use in my components? I don't want to constantly have to make subject variables and call .subscribe
on them because that opens a new websocket connection and the entire app could probably work off of just 1 shared connection.
// I'm also having trouble sending JS objs as the data as well. They should be getting JSON.parsed
// and sent but doing something like this gives an error:
//
// var payload = {"action": "whatever", "message": "my message"}
// console.log(payload)
// console.log(JSON.stringify(payload)) // Do I have to stringify first????
// subject.next(payload);
// ^ GIVES ERROR
// Error with websocket connection: SyntaxError: Unexpected token m in JSON at position 0
// adding deserializer: msg => msg to the subject config fixes this but idk why.
For more context, I am using a AWS api gateways websocket for my backend though I imagine this rxjs library works with any websocket server.
Upvotes: 6
Views: 15693
Reputation: 14750
I think the simplest example would look something like this:
export class WebSocketService {
private socket$ = new webSocket(url);
public messages$ = this.socket$.asObservable();
public sendMessage(msg: any) {
this.socket$.next(msg);
}
}
To adddress your concern:
...because that opens a new websocket connection and the entire app could probably work off of just 1 shared connection.
This is not an issue, RxJs webSocket will only use a single connection. From the docs:
When WebSocketSubject is subscribed, it attempts to make a socket connection, unless there is one made already. This means that many subscribers will always listen on the same socket, thus saving resources
Yes, you need to stringify before sending messages:
...bear in mind that this value will not be serialized beforehand. Because of This, JSON.stringify will have to be called on a value by hand, before calling next
Upvotes: 4