11
votes

I am trying to learn RxJS with websockets and Angular 4, and found a good example here. I'm hoping someone can help explain the example as a few things are confusing.

They have created 2 Angular services, the Websocket Service:

import { Injectable } from '@angular/core';
import * as Rx from 'rxjs/Rx';

@Injectable()
export class WebsocketService {
  constructor() { }

  private subject: Rx.Subject<MessageEvent>;

  public connect(url): Rx.Subject<MessageEvent> {
    if (!this.subject) {
      this.subject = this.create(url);
      console.log("Successfully connected: " + 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 the Chat service:

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs/Rx';
import { WebsocketService } from './websocket.service';

const CHAT_URL = 'ws://echo.websocket.org/';

export interface Message {
    author: string,
    message: string
}

@Injectable()
export class ChatService {
    public messages: Subject<Message>;

    constructor(wsService: WebsocketService) {
        this.messages = <Subject<Message>>wsService
            .connect(CHAT_URL)
            .map((response: MessageEvent): Message => {
                let data = JSON.parse(response.data);
                return {
                    author: data.author,
                    message: data.message
                }
            });
    }
}

I've got a number of questions about this:

  1. Why is it necessary to create 2 services? Can't a Subject be an observer and observable (so it could just relay the messages directly without a second Chat service)? What problem does is solve creating 2 services?
  2. In the Websocket Service, why does the last line of the .create function call return ws.close.bind(ws)? What does that do?
  3. How is a disconnect of the websocket handled? Is there a way to make it reconnect?
  4. How should the services close/dispose of the websocket?
1
Downvoted within seconds of posting? I hope an explanation is forthcoming.TSG
If you have all these questions in mind, what makes you think that example is a good one? :-). To me basic, simple approaches are always better: stackoverflow.com/questions/37025837/… (both answers are simple and useful). Btw, the reason for the downvote is apparently the question is too broad as it's been flagged that way because you asked 4 in 1 question which you basicly expect a very broad, not a specific answer (I also hate reasonless downvotes).eko
There is VERY LITTLE in terms of documentation for websocket+RxJS+ng2 so I'm stuck looking at examples. This is the simplest example I could find....so I'm trying to understand it. I've researched individual pieces, but some don't make sense yetTSG

1 Answers

4
votes
  1. Reuseability
  2. so you can unsubscribe from observable which in turn closes the connection
  3. in the example you gave it would probably be something like (when you have a instance of chatService)

    let sub = chatService.messages.subscribe(()=>{ 
    // do your stuff 
    });
    
    // some where in your code
    sub.unsubscribe() // this will close the connection
    
  4. already answered in 3