The best way to share WebSocket data between multiple components in Angular 2?

折月煮酒 提交于 2019-12-28 15:59:21

问题


I start to build an application. There are a lot of components. Each of them need a part of data from 1 webSocket. The example of a receiveing object by webSocket:

Each Angular 2 component need 1 field from receiveing object. Is it possible to make 1 service, that will connect to webSocket, receive data and share it between all components ? I think it will be a good solution.

Now i'm using the next approach:

getConfigCallback() {
    this.connectionSockets.telemetry = io(this.config.connections.telemetry);
    this.connectionSockets.controlFlow = new WebSocket(this.config.connections.controlFlow.server + ':' + this.config.connections.controlFlow.port);

    this.connectionSockets.telemetry.on('telemetry', function(data) {
        console.log(data);
    });

    this.connectionSockets.controlFlow.onopen = function(data) {
        console.log('onOpen', data);
    };

    this.connectionSockets.controlFlow.onmessage = function(data) {
        console.log('onMessage', data);
    };
}

I receive data in a main component and want to share it between components using component's instances. But i think it's a bad idea and there is exist a better solution.


回答1:


Sure you can share your service by set its provider when bootstrapping the application:

bootstrap(AppComponent, [ WebSocketService ]);

This way you will share the same instance of your service in the whole application. I mean when you inject the WebSocketService service, the corresponding instance will be the same whatever the component / service.

To be able to share the received data, I would leverage an hot observable. By default observables are cold so you need to use the share operator.

initializeWebSocket(url) {
  this.wsObservable = Observable.create((observer) => {
    this.ws = new WebSocket(url);

    this.ws.onopen = (e) => {
      (...)
    };

    this.ws.onclose = (e) => {
      if (e.wasClean) {
        observer.complete();
      } else {
        observer.error(e);
      }
    };

    this.ws.onerror = (e) => {
      observer.error(e);
    }

    this.ws.onmessage = (e) => {
      observer.next(JSON.parse(e.data));
    }

    return () => {
      this.ws.close();
    };
  }).share();
}

Components that would like to receive data from the web socket could use this observable this way:

@Component({
  (...)
})
export class SomeComponent {
  constructor(private service:WebSocketService) {
    this.service.wsObservable.subscribe((data) => {
      // use data
    });
  }
}

See this article for more details in the "event-based approach" section:

  • https://jaxenter.com/reactive-programming-http-and-angular-2-124560.html



回答2:


Something like the following (depending on your concrete requirements):

@Injectable()
class WsService {
  comp1Data = new BehaviorSubject();
  comp2Data = new BehaviorSubject();

  constructor() {
    getData().subscribe( val => {
      ...
      this.compXData.next(someValue);
    });
  }
  ...
}
@Component({...}) 
export class Component1 {
  constructor(wsService:WsService) {
    wsService.comp1Data.subscribe(value => this.data = value);
  }
}
@NgModule({
   directives: [AppComponent, Component1],
   bootstrap: [AppComponent],
   providers: [WsService, ...]
});


来源:https://stackoverflow.com/questions/37025837/the-best-way-to-share-websocket-data-between-multiple-components-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!