javascript - 如何在发射成功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);
})
解决方案
您应该正确地将处理 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);
}
推荐阅读
- java - android studio中的活动在按下按钮后不切换
- android - Azure notification hub dependencies not working
- laravel - 基于租户具有不同权限集的 Laravel 用户
- kendo-ui - 如何在 kendo 中捕获 ajax 服务器故障?
- python - 我的数据生成器没有获取新数据。每次交互都获得相同的数据
- javascript - SMS 权限已从 androidmanifest.xml 中删除,但仍出现在 manifest.class 中
- javascript - 如何 .focus() Javascript 中的 .srcElement / childNode
- jquery - 更改前一个选择器的类 > 子元素
- perl - Perl 如何验证一个路径是一个目录,但又不能同时调用 opendir() 呢?
- java - 在 Spring Boot 中访问多个属性并动态分配的最佳方法