【问题标题】:Angular, Socket.io : Emit an array of objectAngular,Socket.io:发出一个对象数组
【发布时间】:2025-12-19 04:15:11
【问题描述】:

使用 Angular 我如何订阅像这样的对象数组:

[
    'abc/user2': { room: 'abc/user2', user: 'user2' },
    'abc/admin': { room: 'abc/admin', user: 'admin' }
]

目前这不起作用:

this.socketService.onRoom().subscribe(rooms => {
    this.rooms = rooms;
});

socketService:

public onRoom() {
    return new Observable<any>(observer => {
        this.socket.on('room', (data: any) => observer.next(data));
    });
}

编辑:

Mybad,看来问题来自服务器(NodeJS/express/socket.io):

chat-server.ts:

public rooms: Array<{room: string, user:string}> = [];

(...)
this.rooms[room] = {room: room, user: socket.user};
this.io.emit('room', this.rooms)
console.log('[server]rooms :', this.rooms)

服务器端,console.log 打印:

[
    'abc/user2': { room: 'abc/user2', user: 'user2' },
    'abc/admin': { room: 'abc/admin', user: 'admin' }
]

但是socketService 的客户端,如果我在这里做一个console.log(data):

public onRoom() {
    return new Observable<any>(observer => {
        this.socket.on('room', (data: any) => {
            console.log(data)
            observer.next(data)
        });
    });
}

返回:

[]

但如果我发出服务器端:

this.io.emit('room', Object.keys(this.rooms))

客户端返回:

['abc/user2', 'abc/admin']

看起来我无法从 socket.io 发出对象数组?

【问题讨论】:

  • 向我们展示服务中的 onRoom() 方法。
  • @VinkoVorih 已编辑;订阅使用一个简单的字符串数组,但我无法让它使用一个对象数组

标签: javascript node.js angular express socket.io


【解决方案1】:

你不能。你必须把它变成某种可观察的......

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';

export class AppComponent implements OnInit {

    private readonly data = [
        {
            'abc/user2': { room: 'abc/user2', user: 'user2' }
        },
        {
            'abc/admin': { room: 'abc/admin', user: 'admin' }
        }
    ];
    private data$;

    ngOnInit() {
        this.data$ = new Observable((observer) => {
            observer.next(this.data);
            observer.complete();
        });
    this.data$.subscribe(data => {
        console.log(data);
    });
}

尽管有许多其他方法(可能还有更好的方法)来做到这一点。只是给你一个例子,因为我不知道你想要完成什么。

【讨论】:

    【解决方案2】:

    您应该创建要在socket.on 方法之外返回的可观察对象。

    public onRoom(): Observable<any> {
        BehaviorSubject<any> toReturn = new BehaviorSubject();
        this.socket.on('room', (data: any) => toReturn.next(data));
        return toReturn;
    }
    

    【讨论】:

      【解决方案3】:
      private myArray = [
          'abc/user2': { room: 'abc/user2', user: 'user2' },
          'abc/admin': { room: 'abc/admin', user: 'admin' }
      ];
      private myObservable= Observable.of(this.myArray);
      

      届时您可以订阅myObservable

      【讨论】:

        【解决方案4】:

        我终于设法通过不发出对象数组而仅发出一个对象来解决这个问题

        chat-server.ts

        //public rooms: Array<{room: string, user:string}> = [];
        public rooms: any = {};
        

        在客户端,我将我的对象转换为一个数组,这样我就可以将它迭代到模板中。

        chat-list.component.ts

        this.socketService.onRoom().subscribe(rooms => {
            this.rooms = rooms;
            this.roomsArr = Object.entries(this.rooms);
        
        });
        

        不过,我还是不明白为什么我无法从 socket.io 发出一个对象数组

        【讨论】: