Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #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 для отправки сообщения на сервер.

Прошу помочь разобраться!
Может быть есть официальная документация на этот счет? Желательно, конечно, на русском, но можно и на английском, лишь бы была понятная (это важно )
Ответить с цитированием
  #2 (permalink)  
Старый 26.06.2018, 13:44
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Цитата:
Это тот же самый observer.next?
Нет. Это тот observer, который где-то в коде вызвал метод connect и соответственно подписался на получение уведомлений. Никакого отношения к socket.io он не имеет - это чисто rxjs сущность.
Цитата:
Если нет - откуда он берётся
из замыкания
Цитата:
Может быть есть официальная документация на этот счет?
https://www.learnrxjs.io/
Ответить с цитированием
  #3 (permalink)  
Старый 26.06.2018, 14:56
Новичок на форуме
Отправить личное сообщение для Nelkor Посмотреть профиль Найти все сообщения от Nelkor
 
Регистрация: 26.06.2018
Сообщений: 5

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

Впрочем, всё равно есть непонятный момент:

this.chat.messages.subscribe(msg => {
    console.log('Данные из подписки:');
    console.log(msg);
});


console.log подписан на this.chat.messages

sendMessage() {
    this.chat.sendMsg("Test Message");
}


sendMsg юзает this.messages.next

Предполагается, однако, что при этом сообщение будет отправлено на сервер, а не подписчику. И ведь так и происходит. А почему?)
Ответить с цитированием
  #5 (permalink)  
Старый 26.06.2018, 17:50
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Nelkor,
Пока не разобраться в документации, так и будут вопросы появляться на каждый случай. Лучше потратить день-два и все встанет на свои места.
Ответить с цитированием
  #6 (permalink)  
Старый 26.06.2018, 18:03
Новичок на форуме
Отправить личное сообщение для Nelkor Посмотреть профиль Найти все сообщения от Nelkor
 
Регистрация: 26.06.2018
Сообщений: 5

С одной стороны - да. С другой - если Вы знаете ответ, то почему бы не сказать его

Кроме того, обладая какими-то знаниями, изучать документацию легче, нежели с нуля.
Ответить с цитированием
  #7 (permalink)  
Старый 26.06.2018, 18:17
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

this.messages = wsService.connect();

здесь в messages запишется Subject. Когда я пишу messages.next('Блаблабла'), то вызывается метод next вот такой
const observer = {
    next: (data: Object) => { // next отправляет данные на сервер
      console.log('Отправка данных на сервер...');
      this.socket.emit('message', JSON.stringify(data));
    },
  };

который и отправляет данные на сервер.
А вот эта конструкция
const observable = new Observable(observer => {
    this.socket.on('message', (data) => {
      console.log("Данные пришли с сервера");
      observer.next(data); // Я вызываю next, но данные отправляются не на сервер, а подписчику
    })
  });

срабатывает когда у меня где-то в коде есть messages.subscribe().
То есть в Subject можно как писать новые значения, так и подписываться на него. В первом случае вызывается метод next объекта Observer (первый аргумент в методе Subject.create), во втором - определенная мной Observable (второй аргумент в методе Subject.create).
Ответить с цитированием
  #8 (permalink)  
Старый 26.06.2018, 18:33
Новичок на форуме
Отправить личное сообщение для Nelkor Посмотреть профиль Найти все сообщения от Nelkor
 
Регистрация: 26.06.2018
Сообщений: 5

На самом деле стало понятнее
Спасибо!
Ответить с цитированием
  #9 (permalink)  
Старый 27.06.2018, 20:11
Аватар для xShift
Профессор
Отправить личное сообщение для xShift Посмотреть профиль Найти все сообщения от xShift
 
Регистрация: 22.11.2016
Сообщений: 212

Возможно я глупый, но у меня вопрос. А что на строки обсервер и инжектабл у вас член встает, что вы на этом тс потом пишете с серьезным лицом?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Angular Universal, серверный рендеринг - нужно ли мне это? yinfo Angular.js 6 29.10.2018 14:17
Преподаватель JavaScript, Angular OxanaAV Работа 3 15.11.2017 08:16
Вакансия: Опытный разработчик Angular / Anguar 2. Москва. AK76 Работа 0 14.08.2017 11:37
Проблема c расширением (За решение проблемы готов платить) Chrome на angular и ajax hylum Angular.js 0 13.01.2017 14:40
Angular task workflow mardoksp Angular.js 0 15.02.2016 21:34