【发布时间】:2019-12-01 07:37:19
【问题描述】:
我正在尝试使用 Angular 和 node.js 中的 socket.io 设置一个实时应用程序,但它没有按预期工作。
每当客户发布新帖子时,其他客户在您与该客户互动之前不会更新(例如,单击页面上的某个位置,或单击浏览器选项卡)。
但是,在浏览器中打开控制台后,我可以在记录帖子/对象时在控制台中看到新帖子 - 无需与客户端交互。
角度:
import io from 'socket.io-client';
const socket = io('http://localhost:3000');
posts: Post[] = [];
...
// Inside ngOnInit:
socket.on('data123', (res) => {
console.log('Updating list..', res);
this.postService.getPosts();
this.postsSub = this.postService.getPostUpdateListener()
.subscribe((posts: Post[]) => {
this.posts = posts;
});
});
在模板中显示:
<... *ngFor="let item of posts">
PostsService 内部:
getPosts() {
this.http.get<{ message: string, posts: Post[] }>('http://localhost:3000/api/posts')
.subscribe((postData) => {
this.posts = postData.posts;
this.postsUpdate.next([...this.posts]);
});
}
Node.js - 这个 socket.io 解决方案尚未发送实际列表:
const io = socket(server);
io.sockets.on('connection', (socket) => {
console.log(`new connection id: ${socket.id}`);
sendData(socket);
})
function sendData(socket){
socket.emit('data123', 'TODO: send the actual updated list');
setTimeout(() => {
console.log('sending to client');
sendData(socket);
}, 3000);
}
按预期工作:
在前端使用 setInterval 而不是 "socket.on(..)" 可以得到预期的结果,这意味着客户端将自动更新而无需交互。我完全知道这个解决方案很糟糕,但我认为这表明 Angular 部分中的套接字解决方案有问题。
【问题讨论】:
-
这似乎是一个变更检测问题。尝试将您的帖子转换为 Observable,然后在 *ngFor 中使用异步标志
-
我认为你是对的。我会尝试转换它,看看效果如何。
-
@Dino 我将帖子更改为 Observable,并在 *ngFor 中添加了异步管道。结果是一样的。您必须进行交互(单击某个组件)才能使其自行更新,这真的很奇怪。使用
setInterval无需交互即可工作,但不能使用socket.on函数。
标签: node.js angular typescript socket.io observable