首页 > 解决方案 > 不能将传递的 socket.io 实例用作事件侦听器

问题描述

我正在为匹配创建nodejs应用程序:当我将套接字实例传递给匹配类时,如果其中一个客户端断开连接并且匹配类中的套接字侦听器不再工作,则连接将终止

服务器.ts

class SocketServer {
    public server: Server;
    public matches: Match[] = [];
    private io: socketIo.Server;

    constructor() {
        this.createServer();
        this.sockets();
        this.listen();
    }

    private createServer(): void {
        this.server = createServer();
    }

    private  sockets(): void {
        this.io = socketIo(this.server);
    }

    private listen(): void {
        this.server.listen(this.port, this.host, () => {
            console.log("http://%s:%s", this.host, this.port);
        });

        const nsp = this.io.of("my-namespace")
            .on("connection", (socket: any) => {
            const query = {
                client_id: Number(socket.handshake.query.client_id),
                match: Number(socket.handshake.query.match) };
            socket.join(query.match.toString());
            socket.on("subscribe", (room: string) => {
                socket.join(room);
            });
            socket.on("unsubscribe", (room: string) => {
                socket.leave(room);
            });
            if (this.matches.length > 0) {
                const match = this.findMatchById(query.match);
                if (match === undefined) {
                    this.matches.push(new Match(nsp, socket, query));
                }
            } else {
                this.matches.push(new Match(nsp, socket, query));
            }
        });
    }

 }

在匹配类中,当我使用io.emit()它时它工作正常,但socket.on()在任何客户端与匹配断开连接后它不起作用

匹配.ts

export default class Match {
    constructor(namespace: any, socket: any, query: any) {
        this.namespace = namespace;
        this.room = query.match.toString();
        this.id = query.match;
        this.main(socket, query);
    }
    public async main(socket: any, query: any) {
        if (this.initiated === false) {
            await this.initMatch();
        }


        socket.on("player-ready", (data: any) => {
            // some code
        });
        socket.on("disconnect", () => {
            // some code
        });
    }    
}

标签: node.jstypescriptsocket.io

解决方案


我发现问题出在哪里,当我将套接字实例传递给 Match 构造函数时,我让一个客户端连接到房间,并且由于条件

if (this.matches.length > 0) {
    const match = this.findMatchById(query.match);
    if (match === undefined) {
        this.matches.push(new Match(nsp, socket, query));
    }
} else {
    this.matches.push(new Match(nsp, socket, query));
}

我从不让其他人在同一个比赛中注册,所以我在比赛类中创建了一些公共方法,并在服务器文件中使用它,如下所示:

匹配.ts

public makeClientReady(id: number): void {
    // some code
}

服务器.ts

const nsp = this.io.of("my-namespace")
        .on("connection", (socket: any) => {
        const query = {
            client_id: Number(socket.handshake.query.client_id),
            match: Number(socket.handshake.query.match) };
        socket.join(query.match.toString());
        socket.on("subscribe", (room: string) => {
            socket.join(room);
        });
        socket.on("unsubscribe", (room: string) => {
            socket.leave(room);
        });
        if (this.matches.length > 0) {
            const match = this.findMatchById(query.match);
            if (match === undefined) {
                this.matches.push(new Match(nsp, socket, query));
            }
        } else {
            this.matches.push(new Match(nsp, socket, query));
        }

        socket.on("player-ready", (data: any) => {
            match.makeClientReady(Number(data.id));
        });
    });

推荐阅读