Угловой: Как я могу получить данные из события внутри службы в свой компонент?

#node.js #angular #typescript #websocket #socket.io

Вопрос:

В настоящее время я пишу угловой проект, который открывает соединение websocket с сервером NodeJS. Это и есть услуга:

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

Мой вопрос: как я могу передать «данные» из прослушивателя широковещательных событий в компонент, чтобы отобразить их там? Другой сервис был бы решением, но я не думаю, что он был бы хорошим. Я также мог бы поместить прослушиватель в функцию и вызвать ее из компонента, но не нарушит ли это концепции инкапсуляции сервисов?

Спасибо

Ответ №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();
    }
  }
}
 

И, с другой стороны, просто подпишитесь на свои данные, которые выдают значения, связанные с поведением объекта.

 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 = [];
  }
}
 

Комментарии:

1. Спасибо вам за вашу помощь! Я действительно застрял здесь, я не мог найти никаких ресурсов по этой проблеме. Я сделаю это сейчас. К сожалению, я не могу поддержать вас, потому что у меня нулевая репутация, иначе я бы

2. Нет проблем, я здесь для того, чтобы помочь, а не для того, чтобы понять суть ;).

3. Эй, у меня есть следующий вопрос. Я решил использовать один веб-сайт, который обрабатывает вход в систему и все остальное. Теперь мне интересно, как я мог бы изменить поведение объекта, чтобы предоставить компоненту только необходимые данные, а не все?

4. Почему бы вам не отправить JSON через сервер, а затем проанализировать его спереди. Обязательно добавьте поле «тип», затем на основе значения «тип» используйте другой объект поведения и подпишитесь на него для достижения своей цели ?