Md Alamin :
I am building a quiz application in NodeJS and Android using socket.IO,
I am facing a problem when I emit an event quizzoStatus
from the server, the event fires first time once, second time twice and so on.
Here I attach my code snippet
///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);
}
});
Here I listen a event named sendQuizzoAnsPoints
and then I emit an event to the player or opponent in another event named quizzoStatus
.
The
quizzoStatus
event fires multiple times from server to android. Here I attached android code
/// 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());
}
});
}
});
Tushar Monirul :
The problem is in Android
. You are assigning new listener every time without removing it. You need to create a variable of that Emmiter
listener and remove it onDestroy
or somewhere else when the work is done:
//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);
}
Hope this will work