Как обработать подтверждение socket.io из service.ts в component.ts при успешном завершении передачи Angular 8 - PullRequest
1 голос
/ 26 апреля 2020

Когда клиент отправляет новое сообщение на сервер с помощью socket.io, сервер отправляет подтверждение вновь созданного messageId с помощью обратного вызова fn (). Я могу войти в messageId в service.ts, но не могу найти способ «получить» messageId для компонента .ts (чтобы обновить вновь созданное сообщение с идентификатором). При использовании приведенного ниже кода я получаю ошибку angular, в которой говорится, что я не могу подписаться на this.appService.newMessage (), даже если я возвращаю Observable нового идентификатора сообщения с of (newMsgId) в service.ts , Пожалуйста, если я могу добавить больше информации, чтобы помочь

server.js
--------

socket.on('newStaffMessage', function (data, fn) {
    var msg = new Message({
      sender: data.senderId,
      content: { text: data.content.text, attachment: null },
      dateTime: new Date(),
    });

    msg.save((err, messageDoc) => {
      Conversation.findByIdAndUpdate(
        { _id: data.conversationId },
        {
          $push: { messages: messageDoc._id },
        },
        { new: true },
        function (err, convoDoc) {
          if (!err) {
            User.findById(data.senderId, function (err, userDoc) {
              const payload = {
                conversationId: convoDoc._id,
                _id: messageDoc._id,
                content: {
                  text: msg.content.text,
                  attachment: msg.content.attachment,
                },
                dateTime: msg.dateTime,
                sender: {
                  _id: userDoc._id,
                  firstName: userDoc.firstName,
                  lastNameInitial: userDoc.lastNameInitial,
                },
              };

              io.in(convoDoc._id).emit('newStaffMessage', payload);
              fn({messageId: messageDoc._id});
            });
          } else {
            console.log(err);
          }
        }
      );
    });
  });
service.ts
----------

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Observer, of } from 'rxjs';
import * as io from 'socket.io-client';

@Injectable({
  providedIn: 'root',
})
export class AppService {
  private socket = io('http://localhost:3000');

  constructor(private http: HttpClient) {}

  newMessage(msg) {
    this.socket.emit('newStaffMessage', msg, (newMsgId) => {
      return of(newMsgId);
    });
  }
component.ts
------------
this.appService.newMessage(newMessage).subscribe(data => {
      console.log(data);
    })

1 Ответ

0 голосов
/ 26 апреля 2020

Вы должны правильно преобразовать обработку события socket.io с обратным вызовом в Observable.

Я бы предложил здесь два варианта:

1) Использовать конструктор Observable или оператор create с заданной функцией подписки:

import { Observable } from 'rxjs';
...
newMessage(msg) {
  return Observable.create(observer => {
    this.socket.emit('newStaffMessage', msg, (newMsgId) => {
      observer.next(newMsgId);
    });
  });
}

2) Использование, предназначенное для таких целей Rx JS bindCallback Функция:

import { bindCallback } from 'rxjs';

newMessage(msg) {
  return bindCallback(this.socket.emit)('newStaffMessage', msg);
}
...