node.js - 不能将传递的 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
});
}
}
解决方案
我发现问题出在哪里,当我将套接字实例传递给 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));
});
});
推荐阅读
- c++ - Qt:在类函数中创建对象时如何使用插槽
- mysql - mysql> SELECT COUNT(*) vs SHOW TABLE STATUS 的行数
- c# - C#:测试实体框架 FromSql 以确保正确的语法
- android - Kotlin 未配置:Android 工作室
- javascript - 在 HTML 中单击时如何更改按钮的图像
- flutter - Flutter 使用 map 函数为列表中的每个元素创建一个无状态的小部件
- eclipse - 线程“主”java.lang.NoClassDefFoundError 中的异常:运行 TestNG 文件时出现 org/testng/TestNG 错误
- continuous-integration - Terraform 从环境中读取变量
- docker - docker compose 会自动创建端口映射吗?
- python - 按钮命令在 tkinter 中自动执行