Я создаю приложение nodejs для матчей: когда я передаю экземпляр сокета в класс соответствия, соединение обрывается, если один из клиентов отключается, а прослушиватель сокетов в классе соответствия больше никогда не работает
server.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.info("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() не работает после того, как какой-либо клиент отключился от матча
match.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));
}
я никогда не позволяю никому другому регистрироваться в том же матче, поэтому я создал несколько общедоступных методов в классе match и использовал их в файле сервера следующим образом:
match.ts
public makeClientReady(id: number): void {
// some code
}
server.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));
});
});