Показать сообщение отдельно
  #1 (permalink)  
Старый 26.06.2018, 13:24
Новичок на форуме
Отправить личное сообщение для Nelkor Посмотреть профиль Найти все сообщения от Nelkor
 
Регистрация: 26.06.2018
Сообщений: 5

Angular 6, rxjs, Обсерверы и Обсервируемые
Всем привет!
Пишу Hello-World приложение на Angular, используя библиотеку socket.io. Официальных руководств не нашел, так что информацию брал просто из интернета. Ключевые файлы в проекте следующие:

websocket.service.ts
import { Injectable } from '@angular/core';
import * as io from 'socket.io-client';
import { Observable, Subject } from 'rxjs';
 
@Injectable()
export class WebsocketService {
  private host = 'localhost:5000';
  private socket;
 
  constructor() {}
 
  connect(): Subject<MessageEvent> {
  this.socket = io(this.host);
 
  const observable = new Observable(observer => {
    this.socket.on('message', (data) => {
      console.log("Данные пришли с сервера");
      observer.next(data); // Я вызываю next, но данные отправляются не на сервер, а подписчику
    })
  });
 
  const observer = {
    next: (data: Object) => { // next отправляет данные на сервер
      console.log('Отправка данных на сервер...');
      this.socket.emit('message', JSON.stringify(data));
    },
  };
 
  return Subject.create(observer, observable);
  }
}


chat.service.ts
import { Injectable } from '@angular/core';
import { WebsocketService } from './websocket.service';
import { Observable, Subject } from 'rxjs';
import { map } from 'rxjs/operators';
 
@Injectable()
export class ChatService {
  messages: Subject<any>;
 
  constructor(private wsService: WebsocketService) {
    this.messages = wsService.connect();
  }
 
  sendMsg(msg) {
    this.messages.next(msg);
  }
}


app.component.ts
import { Component, OnInit } from '@angular/core';
import { ChatService } from './chat.service';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
 
  constructor(private chat: ChatService){ }
 
  ngOnInit() {
    this.chat.messages.subscribe(msg => {
      console.log('Данные из подписки:');
      console.log(msg);
    });
  }
 
  sendMessage() {
    this.chat.sendMsg("Test Message");
  }
}


Следует отметить, что всё работает. Но почему работает - не ясно .

Конкретнее:
В websocket-сервисе определён объект observer с методом next. Его работа - отправлять сообщения на сервер. Этому методу подошло бы другое имя, но присвоить ему другое имя нельзя - возникает ошибка. Впрочем, ладно, это может быть связано с Subject.create. Дело-то в другом:
const observable = new Observable(observer => {
    this.socket.on('message', (data) => {
        console.log("Данные пришли с сервера");
        observer.next(data); // Я вызываю next, но данные отправляются не на сервер, а подписчику
    })
});


При получении сокетом сообщения, вызывается observer.next. Это тот же самый observer.next? Если да - почему он отправляет данные не на сервер, а подписчику? Если нет - откуда он берётся и почему имеет имя уже существующего элемента и вносит неразбериху в код?

Понятно, что он и должен отправлять данные подписчику по логике приложения. Я не хочу пинговать сервер бесконечным потоком сообщений. Но я хочу понять, почему это делается именно методом observer.next.

Взять, например, тот же chat-сервис:
sendMsg(msg) {
    this.messages.next(msg);
}


Функция sendMsg использует метод next для отправки сообщения на сервер.

Прошу помочь разобраться!
Может быть есть официальная документация на этот счет? Желательно, конечно, на русском, но можно и на английском, лишь бы была понятная (это важно )
Ответить с цитированием