通过可观察到的服务类将数据从Web套接字馈入组件

时间:2018-09-04 10:00:01

标签: angular websocket rxjs

我有一个连接到Web套接字以接收数据的应用程序。数据馈送只是一种方式,因此客户端不会将数据推送到服务器

我创建了一个WebSocketService,它订阅了Web套接字(使用stomp),然后在出现消息时将数据推送到可观察的

private createSocketObservable<T>(topic: string) {
    return Observable.create((obs: Observer<T>) => {
        // Subscribe to the topic, and on each message the observer pushes the parsed data
        const subscription = this.stompClient.subscribe(topic, (message: Message) => {
            const jsonData = JSON.parse(message.body);
            obs.next(jsonData);
        });
        this.subscriptions.push(subscription);

    });
}

然后,我希望拥有不同的服务类,这些服务类订阅Web套接字上的不同主题,并将上述可观察到的数据传递给组件,可能会在途中修改或过滤该数据(例如,使用map)

我已经创建了一个抽象的WebSocketSubscription类,这些服务可以扩展该类,其中包含从WebSocketService返回的可观察对象

export abstract class WebSocketSubscriber<T> {
    abstract topic: string;

    webSocketFeed: Observable<T>;

    constructor(private webSocketService: WebSocketService) {
        this.webSocketService.connect().then(() => {
        this.webSocketFeed = this.webSocketService.getObservable(this.topic);
    });
}

我现在如何设置它,以便任何扩展WebSocketSubscriber的服务类都可以调用诸如map,distinct,filter等功能,并且组件可以订阅该提要的结果?

此外,组件的订阅可能会在连接Web套接字之前发生,我最初的想法是使用Promise等待连接完成,但是我想知道是否有RxJs的方法也可以处理

1 个答案:

答案 0 :(得分:1)

使用ReplaySubject,您可以记住先前订阅的服务的先前主题消息:

@Injectable()
export class WebSocketServiceService {

  private socketSubjects: { [key: string]: ReplaySubject<any> } = {}

  private createSocketObservable<T>(topic: string) {
    if(this.socketSubjects[topic]){
      return this.socketSubjects[topic].asObservable();
    }
    else{
      this.socketSubjects[topic] = new ReplaySubject();
      const subscription = this.stompClient.subscribe(topic, (message: Message) => {
      const jsonData = JSON.parse(message.body);
      this.socketSubjects[topic].next(jsonData);
    });
    this.subscriptions.push(subscription);
    }
  }
}

创建ReplaySubject时,您可以设置内存限制:

new ReplaySubject(5) // remember last 5 items