typescript Angular 4 中的 Websocket 和 RxJS 混淆

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45968054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:51:30  来源:igfitidea点击:

Websocket in Angular 4 and RxJS confusion

angulartypescriptwebsocketrxjs

提问by TSG

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.

我正在尝试使用 websockets 和 Angular 4 来学习 RxJS,并在这里找到了一个很好的例子。我希望有人能帮助解释这个例子,因为有些事情令人困惑。

They have created 2 Angular services, the Websocket Service:

他们创建了 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);
  }

}

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. 为什么需要创建2个服务?主题不能是观察者和可观察者(因此它可以直接中继消息而无需第二个聊天服务)?解决创建 2 个服务的问题是什么?
  2. 在Websocket Service中,为什么.create函数调用的最后一行返回ws.close.bind(ws)?那有什么作用?
  3. 如何处理 websocket 断开连接?有没有办法让它重新连接?
  4. 服务应该如何关闭/处理 websocket?

采纳答案by Arin

  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

  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 中回答