首页 > 解决方案 > 如何在发射成功Angular 8时处理从service.ts到component.ts的socket.io确认

问题描述

当客户端使用 socket.io 向服务器发送新消息时,服务器会使用回调 fn() 发送对新创建的 messageId 的确认。我能够在 service.ts 中记录 messageId,但无法找到将 messageId“获取”到组件 .ts 的方法(以便使用 ID 更新新创建的消息)。通过下面设置代码的方式,我收到一个角度错误,说我无法订阅 this.appService.newMessage(),即使我在 service.ts 中返回带有 of(newMsgId) 的新消息 ID 的 Observable。如果我可以添加更多信息来帮助,请 lmk

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

标签: javascriptnode.jsangularsocket.iomean-stack

解决方案


您应该正确地将处理 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) 使用专用于此类目的的 RxJS bindCallback函数:

import { bindCallback } from 'rxjs';

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

推荐阅读