【问题标题】:Angular: How do I get data from an event inside a service to my component?Angular:如何从服务内的事件中获取数据到我的组件?
【发布时间】:2021-11-23 00:02:16
【问题描述】:

我目前正在编写一个 Angular 项目,它打开与 NodeJS 服务器的 websocket 连接。这是服务:

export class WebsocketService {

  socket : any;

  constructor() { }

  setupSocketConnection(){
    this.socket = io(environment.SOCKET_ENDPOINT);
    this.socket.emit('message', 'The client wants to intruduce itself to the server');

    this.socket.on('broadcast', (data: string) => {
      console.log(data);
    });
  }

  disconnect() {
    if (this.socket) {
      this.socket.disconnect();
    }
  }
}

这是我的组件:

export class AppComponent {
  title = '-'; 

  constructor(private websocket : WebsocketService) { }

  ngOnInit(){
    this.websocket.setupSocketConnection();
  }

  ngOnDestroy() {
    this.websocket.disconnect();
  }
}

我的问题是:如何将“数据”从广播事件侦听器传递到组件中以在那里显示?另一项服务将是一个解决方案,但我认为这不是一个好的解决方案。我也可以将监听器放到一个函数中,然后从组件中调用它,但这不会违反服务的封装概念吗?

谢谢

【问题讨论】:

    标签: node.js angular typescript websocket socket.io


    【解决方案1】:

    您可以按照以下步骤使用 BehaviorSubject:

    想象一下发送 JSON 对象包含一个“类型”字段:确保对发送的数据进行字符串化

    1- 服务器端:

    JSON.stringify({type: "message", value: "whatever"})
    

    2- 现在是客户端

    export class WebsocketService {
    
      // Put the right data type here
      message = new BehaviorSubject<string>('');
      connection = new BehaviorSubject<string>('');
    
      socket : any;
    
      constructor() { }
    
      setupSocketConnection(){
        this.socket = io(environment.SOCKET_ENDPOINT);
        this.socket.emit('message', 'The client wants to intruduce itself to the server');
    
        this.socket.on('broadcast', (data: string) => {
          const jsonObject = JSON.parse(data);
          switch (jsonObject.type) {
            case "message":
              this.message.next(jsonObject.value);
              break;
    
            case "connection":
              this.connection.next(jsonObject.value);
              break;
    
            default:
              throw new Error('Unknown message type' + jsonObject.type)
              break;
          }
        });
      }
    
      disconnect() {
        if (this.socket) {
          this.socket.disconnect();
        }
      }
    }
    

    另一方面,只需订阅您的数据 behaviorSubject 发出的值。

    export class AppComponent implements OnInit, OnDestroy {
      title = '-'; 
    
      subscriptions: Subscription[] = [];
      constructor(private websocket : WebsocketService) { }
    
      ngOnInit(){
        this.websocket.setupSocketConnection();
        this.websocket.message.subscribe(value => {
            // Do your stuff here.
            console.log(value);
        })
    
        this.websocket.connection.subscribe(value => {
            // Do your stuff here.
            console.log(value);
        })
      }
    
      ngOnDestroy() {
        this.websocket.disconnect();
        this.subscriptions.forEach(s => s.unsubscribe());
        this.subscription = [];
      }
    }
    

    【讨论】:

    • 感谢您的帮助!我真的被困在这里,我找不到有关此问题的任何资源。我现在将实施这一点。可悲的是我不能投票给你,因为我的声誉为零,否则我会
    • 没问题,我是来帮忙的,不是抓点;).
    • 嘿,我有一个后续问题。我决定使用一个 websocket 来处理登录和其他所有事情。现在我想知道如何将 BehaviorSubject 更改为只为组件提供所需的数据而不是所有内容?
    • 为什么不通过服务器发送JSON,然后在前面解析。确保添加“类型”字段,然后根据“类型”值,使用不同的 BehaviorSubject 并订阅它以实现您的目标?
    猜你喜欢
    • 1970-01-01
    • 2020-07-01
    • 2020-01-16
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多