Socket IO事件多次触发NodeJS
Posted
技术标签:
【中文标题】Socket IO事件多次触发NodeJS【英文标题】:Socket IO event firing multiple times NodeJS 【发布时间】:2019-07-05 15:49:20 【问题描述】:我正在使用 socket.IO 在 NodeJS 和 android 中构建一个测验应用程序,
当我从服务器发出事件quizzoStatus
时遇到问题,该事件第一次触发一次,第二次触发两次,依此类推。
这里附上我的代码sn-p
///server side: NodeJS
socket.on('sendQuizzoAnsPoints', async (data)=>
try
const obj = JSON.parse(data);
const game = await QuizzoPlayModel.findOne(_id:obj.gameId);
const player = await UserModel.findOne(_id: game.playerId);
const opponent = await UserModel.findOne(_id: game.opponentId);
if(obj.userId == game.opponentId)
let update =
opponentPoints: game.opponentPoints + obj.points || 0,
opponentWA: game.opponentWA + obj.wrongAns || 0,
;
await QuizzoPlayModel.findByIdAndUpdate(obj.gameId, update).lean().exec();
userNamespace.to(player.socketId).emit('quizzoStatus',
fullName: opponent.fullName,
points: game.playerPoints + obj.points,
wrongAns: obj.wrongAns,
gameId: obj.gameId
);
if(obj.userId == game.playerId)
let update =
playerPoints: game.playerPoints + obj.points || 0,
playerWA: game.playerWA + obj.wrongAns || 0,
;
await QuizzoPlayModel.findByIdAndUpdate(obj.gameId, update).lean().exec();
userNamespace.to(opponent.socketId).emit('quizzoStatus',
fullName: player.fullName,
points: game.playerPoints+ obj.points,
wrongAns: obj.wrongAns,
gameId: obj.gameId
);
catch (e)
console.log(e);
);
在这里我监听一个名为 sendQuizzoAnsPoints
的事件,然后在另一个名为 quizzoStatus
的事件中向玩家或对手发出一个事件。
quizzoStatus
事件从服务器多次触发到 android。 这里我附上了android代码
/// Android code
socket.emit("sendQuizzoAnsPoints", new Gson().toJson(quizzoStatusRequestDto));
socket.on("quizzoStatus", new Emitter.Listener()
@Override
public void call(Object... args)
runOnUiThread(new Runnable()
@Override
public void run()
Log.e("opponet point", opponentPoints + " " + quizzoStatusResponseDto.getPoints());
);
);
【问题讨论】:
似乎您的客户端(android)多次连接到服务器 我已经查过了,客户端连接了一次,但同时有两个或多个客户端从不同的设备连接。 每台设备都连接同一个ID? 不,每台设备都使用不同的 ID 连接。 @ŞivāSankĂr 服务器重启后记录所有连接的设备(ID)。只需将console.log()
放在socket.join()
之前即可
【参考方案1】:
问题出在Android
。您每次都在分配新的侦听器,而不会删除前一个侦听器。您需要创建该 Emmiter
侦听器的变量,并在工作完成后将其删除到 onDestroy
或其他地方:
//variable of Emmiter.Listener
Emmiter.Listener quizzoStatus = new Emitter.Listener()
@Override public void call(Object... args)
runOnUiThread(new Runnable()
@Override public void run()
Log.e("opponet point", opponentPoints + " " + quizzoStatusResponseDto.getPoints());
);
;
//assigning the listener
socket.on("quizzoStatus", quizzoStatus);
. . . .
@Override protected void onDestroy()
super.onDestroy();
//removing the listener...
socket.off("quizzoStatus", quizzoStatus);
希望这会奏效
【讨论】:
这在上传照片/媒体后从 onActivityResult 返回时也很有用...附加了较早的侦听器并附加了新的侦听器...对我来说它适用于 onStop以上是关于Socket IO事件多次触发NodeJS的主要内容,如果未能解决你的问题,请参考以下文章
如何在前端获取 socket.on 函数?事件被触发和处理。我正在使用 socket.io、NodeJS 服务器和 Redis.io
socket.io 监听器在功能性 React 中触发太多次