使用Observables包装套接字时出现问题 - MaxListenersExceededWarning:检测到可能的EventEmitter内存泄漏

时间:2018-06-08 16:33:12

标签: node.js websocket socket.io rxjs

我有一个 socket.io 服务器,我在其中定义了一个名为SocketObs的简单类来包装带有Observable的套接字。

代码如下

class SocketObs {
    constructor(private socket: any) {}
    onEvent(event): Observable<any> {
        return new Observable<any>((observer: Observer<any>) => {
            this.socket.on(event, data => observer.next(data));
        });
    }
}

服务器本身由类MyServer实现,其代码为

export class MyServer {
    public static readonly PORT = 8081;

    private app: express.Application;
    private server: Server;
    private io: socketIo.Server;
    private port: string | number;

    private observables = new Array<any>();

    constructor() {
        this.app = express();
        this.port = process.env.PORT || MobileObjectServer.PORT;
        this.server = createServer(this.app);
        this.io = socketIo(this.server);
        this.listen();

        for(let i = 0; i < 20; i++) {
            this.observables.push(from([1, 2, 3]))
        }
    }

    private listen() {
        this.server.listen(this.port, () => {
            console.log('Running server STRESS on port %s', this.port);
        });

        this.io.on('connect', socket => {
            console.log('Connected client on port %s.', this.port);
            const socketObs = new SocketObs(socket);
            socketObs.onEvent('monitor')
            .subscribe(
                () => this.monitoSubscribeToObservables(socketObs)
            )
        });
    }

    private monitoSubscribeToObservables(socket: SocketObs) {
        this.observables.forEach(obs => {
            obs
            .pipe(takeUntil(socket.onEvent('disconnect')))
            .subscribe(null, null, () => console.log('observable completed'));
        })
    }

    public getApp(): express.Application {
        return this.app;
    }

}

逻辑非常简单

  • 创建服务器时,它会填充一个包含20个Observables的数组
  • 它设置为聆听模式并等待直到监听&#39;消息到达
  • 当&#39;监视器&#39;消息到达时,它订阅了Observables 在开始时创建
  • 当套接字完成时,Observable订阅完成 断开连接(是的,我知道事实并非如此,但我 需要让takeUntil运营商来解决我的问题)

如果我在节点中运行服务器,我会执行逻辑但是我收到以下警告

(node:76408) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 disconnect listeners added. Use emitter.setMaxListeners() to increase limit

如果我做同样的事情但不使用,即使用此实现

 private listen() {
        this.server.listen(this.port, () => {
            console.log('Running server STRESS on port %s', this.port);
        });

        this.io.on('connect', socket => {
            console.log('Connected client on port %s.', this.port);

            socket.on('monitor', () => {
                this.monitoSubscribeToObservables(socket);
            });

        });
    }

    private monitoSubscribeToObservables(socket: socketIo.Socket) {
        const monitorDisconnected = new Subject<any>();
        this.observables.forEach(obs => {
            obs
            .pipe(takeUntil(monitorDisconnected))
            .subscribe(null, null, () => console.log('observable completed'));
        })
        socket.on('disconnect', () => {
            console.log('Monitor disconnected');
            monitorDisconnected.next();
        });
    }

不再提出警告。

我正在努力理解这种不同行为的原因。

0 个答案:

没有答案