web-dev-qa-db-ja.com

Angular 4とRxJSの混乱のWebsocket

私はwebsocketとAngular 4でRxJSを学ぼうとしていますが、良い例 ここ を見つけました。紛らわしい。

彼らは2つのAngularサービス、Websocketサービスを作成しました:

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);
  }

}

チャットサービス:

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
                }
            });
    }
}

これについて多くの質問があります。

  1. なぜ2つのサービスを作成する必要があるのですか?サブジェクトをオブザーバーおよびオブザーバブルにすることはできません(したがって、2番目のチャットサービスなしでメッセージを直接リレーできます)。 2つのサービスの作成を解決するのはどのような問題ですか?
  2. Websocketサービスで、.create関数呼び出しの最後の行がws.close.bind(ws)を返すのはなぜですか?それは何をしますか?
  3. WebSocketの切断はどのように処理されますか?再接続させる方法はありますか?
  4. サービスはどのようにwebsocketを閉じ/破棄する必要がありますか?
11
TSG
  1. 再利用性
  2. したがって、observableからサブスクライブを解除して、接続を閉じることができます
  3. 指定した例では、おそらくchatServiceのインスタンスがある場合のようになります。

    let sub = chatService.messages.subscribe(()=>{ 
    // do your stuff 
    });
    
    // some where in your code
    sub.unsubscribe() // this will close the connection
    
  4. すでに3で回答済み

4
Arin