RxJs Observables avec WebSocket
Mon angulaire application utilise un websocket pour communiquer avec le backend.
Dans mon cas de test, j'ai 2 composants du client. Les Observables de la minuterie imprime deux clients différents id comme prévu.
Chaque ngOnInit() imprime également l'id de son client.
MAINTENANT pour une raison quelconque, l'abonnement de websocketService.observeClient() est appelé 2 fois pour chaque message, mais this.client.id
toujours imprime la valeur de la deuxième client.
Heres mon composant client
@Component({
...
})
export class ClientComponent implements OnInit {
@Input() client: Client;
constructor(public websocketService: WebsocketService) {
Observable.timer(1000, 1000).subscribe(() => console.log(this.client.id));
}
ngOnInit() {
console.log(this.client.id);
this.websocketService.observeClient().subscribe(data => {
console.log('message', this.client.id);
});
}
}
Et mon websocket Service
@Injectable()
export class WebsocketService {
private observable: Observable<MessageEvent>;
private observer: Subject<Message>;
constructor() {
const socket = new WebSocket('ws://localhost:9091');
this.observable = Observable.create(
(observer: Observer<MessageEvent>) => {
socket.onmessage = observer.next.bind(observer);
socket.onerror = observer.error.bind(observer);
socket.onclose = observer.complete.bind(observer);
return socket.close.bind(socket);
}
);
this.observer = Subject.create({
next: (data: Message) => {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(data));
}
}
});
}
observeClient(): Observable<MessageEvent> {
return this.observable;
}
}
Modifier
Ok comme ce que j'ai lu, il a à voir avec le fait que les phénomènes Observables sont unicast objets et je dois utiliser un Sujet pour ça, mais je ne sais pas comment créer le Sujet.
providers
de configuration? À partir de votre description, il semble que vous voulez que chaque composant client pour avoir sa propre instance de WebsocketService
.Pas de il devrait être injecté websocketService qui est connecté à l'arrière-plan
OriginalL'auteur Pascal | 2017-04-10
Vous devez vous connecter pour publier un commentaire.
De rxjs 5, vous pouvez utiliser le haut-websocket fonction qui crée le sujet pour vous. Elle aussi se reconnecte quand vous réabonner à la cours d'eau après une erreur. Veuillez vous référer à cette réponse:
https://stackoverflow.com/a/44067972/552203
TLDR:
aussi n'est Observable.webSocket utilise stomp point de fin ? je m à l'aide de printemps et j'ai enregistrer stomp point de fin. j'ai essayé cet exemple, mais je continue à voir l'erreur poignée de main
OriginalL'auteur Herman
Bien, j'ai souffert avec les websockets angulaire et python pour longtemps. J'ai eu quelques websockets pour chaque composant et ils n'ont pas de proches, de sorte que chaque fois que je passe par le biais d'un onglet à l'autre (changement entre les composants), le websocket a été créé de nouveau dans le dos et j'ai été reçu deux fois ou plusieurs fois le même.
Il existe de nombreux tutoriels expliquant comment faire des websockets, mais pas beaucoup, en expliquant comment fermer ou comment plusieurs d'entre eux.
Ici mon morceau de pain:
Le meilleur tuto que j'ai trouvé un peu loin:
https://medium.com/@lwojciechowski/websockets-with-angular2-and-rxjs-8b6c5be02fac
Mais pas encore complet. Il n'est pas de fermer correctement le WS
Ici ce que j'ai fait: (Ma classe WebSocketTestService)
Et ici (dans un autre fichier pour moi) le websocket classe
Et enfin, mon appel à la WSTestService dans le composant
et dans la partie la plus importante, la ngOnDestroy()
Bien sûr, ajouter les deux services pour les fournisseurs de la section de l'application.module
C'est le seul moyen que j'ai trouvé pour fermer correctement le websocket quand j'ai changer entre les points de vue et je détruis les composants. Je ne suis pas vraiment sûr si c'est votre cas, mais il est difficile pour moi de trouver un exemple qui fonctionne correctement avec de multiples points de vue et les websockets. J'ai eu des problèmes similaires à ceux que vous avez demandé, donc j'espère que cela fonctionne pour vous. Laissez-moi savoir si mon approche qui fonctionne pour vous.
Vraiment ce que je ne comprends pas c'est pourquoi Angulaire des appels tous les ngOnInit de chaque composants, même si elles ne sont pas affichées lors du démarrage de l'application. Je veux créer le WS seulement quand je rentre dans la vue, et non pas lors du démarrage de l'application. Si vous trouvez une solution pour que, alors laissez-moi savoir.
bonne chance!
Merci beaucoup aidé. Mais qu'en est-il lorsque le même socket de connexion doit être utilisé dans tous les point de vue.
OriginalL'auteur Javier
Vous devez utiliser le
share
opérateur de la partager entre les abonnés.Assurez-vous également que ce service est un singleton.
Doc: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md
OriginalL'auteur eko