Я сталкиваюсь с той же проблемой, что и этот старый вопрос без реального решения.Я не могу найти хороший способ сохранить как «this» контекст сокета, чтобы получить идентификатор сокета от отправителя, так и «this» контекст моего класса.Вот пример того, что я хочу сделать:
class MyGame
{
constructor(roomId)
{
this.roomId = roomId;
this.players = {};
this.actions = {};
this.actions['room_leave'] = this.onRoomLeft;
this.actions['game_init'] = this.onGameInited;
}
/***********************************/
/********** Class methods **********/
/***********************************/
initPlayer(playerId, playerSocket)
{
this.players[playerId] = playerSocket;
for (var eventName in this.actions)
playerSocket.on(eventName, this.actions[eventName]);
}
startGame()
{
// if players are ready, start the game
}
punishLeaver(socketId)
{
// leaver process
}
/***********************************/
/********* SocketIO events *********/
/***********************************/
onRoomLeft(data)
{
// if I want the socket ID of leaver, I just have to call
// 'this.id' in the event context.
// But I'll cannot call any methods from current class :
this.punishLeaver(this.id) // will obviously not work, this.punishLeaver is undefined
}
onGameInited(data)
{
// if I want to call a class method or member, I have to
// use 'bind(this)', but I lose the 'this' context of event,
// and I'll not be able to emit a message to the sender
this.startGame(); // will work only if i'm using bind(this)
}
}
Здесь я просто хочу вызвать initPlayer (), чтобы добавить новых игроков, и если я получу какой-либо сигнал socketIO от клиентов, я хочу сделать то, чтоэто описано в событиях onRoomLeft и onGameInited.
Когда я использую bind (), я определенно теряю свой объект события сокета и всю информацию из моего клиента отправителя, и другим способом, если я не используюbind (), я не могу вызывать методы моего класса.
Я не профессионал в nodejs, я искал и пробовал множество решений без успеха.Если есть хорошие практики в этом вопросе, мне действительно интересно.
Большое спасибо!
РЕДАКТИРОВАТЬ 1:
Я нашел решениеЯ не до конца понял функцию bind () в документе.Итак, мне просто нужно связать оба экземпляра bind ():
initPlayer(playerId, playerSocket)
{
this.players[playerId] = playerSocket;
for (var eventName in this.actions)
playerSocket.on(eventName, this.actions[eventName].bind(playerSocket, this);
}
И второй параметр bind () будет доступен в качестве параметра в моем обратном вызове события:
onRoomLeft(myGameInstance, data)
{
myGameInstance.punishLeaver(this.id) // will now perfectly works
}