I’m working on a real-time classroom application using Socket.IO where students join a class session and can interact with a teacher. However, I’m encountering an issue with updating the student list when a student reconnects to the class.
Problem Description:
- Initial Setup: When a class session starts, the teacher can see all students who have joined.
- Issue: If a student leaves and then rejoins the class, the student’s name is not shown in the teacher’s student list. This issue occurs only when there are multiple students in the class. If there’s only one student, the list updates correctly when that student rejoins.
What is the issue here. I am totally confused.
// Teacher Side Code
socket.on(socketConstants.START_CLASS_PAGE, async (data: any) => {
const classID = data.classID;
if (!classID) {
return this.io.to(socket.id).emit(socketConstants.START_CLASS_ERROR, {
success: false,
message: 'Class not found',
});
}
socket.join(classID);
await prisma.socketUsers.upsert({
where: { userId: socket.data.user.id },
create: { userId: socket.data.user.id, socketId: socket.id, classID: data.classID },
update: { classID: data.classID },
});
const students = await updateStudentList(classID);
console.log('Students updated:', students);
setTimeout(() => {
this.io.to(classID).emit(socketConstants.UPDATE_STUDENT_LIST, students);
}, 3000);
});
socket.on(socketConstants.START_CLASS, async (startClassData: any) => {
try {
socket.data.isInTest = true;
const classID = startClassData.classID;
if (!classID) {
return this.io.to(socket.id).emit(socketConstants.START_CLASS_ERROR, {
success: false,
message: 'Class not found',
});
}
socket.join(classID);
const classDetails = await checkClassID(classID);
if (!classDetails) {
return this.io.to(socket.id).emit(socketConstants.START_CLASS_ERROR, {
success: false,
message: 'Class details not found',
});
}
if (classDetails.startClass === false) {
const allQuestions = classDetails.classQuestionTypeQuestions.map(item => item.id);
await prisma.currentQuestion.upsert({
where: { classID },
create: { classID, classQuestionTypeQuestionsId: allQuestions[0] },
update: { classQuestionTypeQuestionsId: allQuestions[0] },
});
}
const successData = await startClassEventHandler(classID);
const students = await updateStudentList(classID);
console.log('Students updated:', students);
this.io.to(classID).emit(socketConstants.UPDATE_STUDENT_LIST, students);
this.io.to(classID).emit(socketConstants.START_CLASS_SUCCESS, successData);
} catch (error: any) {
console.log('Start class error:', error);
this.io.to(socket.id).emit(socketConstants.START_CLASS_ERROR, {
success: false,
message: 'Start class failed',
error: error.message,
});
}
});
//Student Side Code
socket.on(socketConstants.JOIN_CLASS, async (joinClassData) => {
try {
socket.data.isInTest = true;
const data = joinClassData;
await socket.join(data.classID);
console.log(`Socket joined room: ${data.classID}`);
const classData = await checkClassID(data.classID);
if (!classData) {
return this.io.to(socket.id).emit(socketConstants.JOIN_CLASS_ERROR, {
success: false,
message: 'Class ID not found',
});
}
await prisma.socketUsers.upsert({
where: {
userId: socket.data.user.id,
},
create: {
userId: socket.data.user.id,
socketId: socket.id,
classID: data.classID,
},
update: {
classID: data.classID,
},
});
const hasClassStarted = classData.startClass ? true : false;
const onlineStudents = await updateStudentList(data.classID);
console.log('online students: ' + onlineStudents);
this.io.to(data.classID).emit(socketConstants.UPDATE_STUDENT_LIST, onlineStudents);
this.io.to(socket.id).emit(socketConstants.JOIN_CLASS_SUCCESS, {
success: true,
message: 'Class joined successfully',
classID: data.classID,
hasClassStarted: hasClassStarted,
});
if (hasClassStarted) {
const currentQuestion = await getCurrentQuestion(data.classID);
if (currentQuestion) {
const questions = await getCurrentQuestionOfClass(
data.classID,
currentQuestion?.classQuestionTypeQuestionsId,
);
if (questions) {
setTimeout(() => {
this.io.to(socket.id).emit(socketConstants.STUDENT_QUESTION, questions.studentQuestion);
}, 3000);
}
}
}
} catch (error: any) {
return this.io.to(socket.id).emit(socketConstants.JOIN_CLASS_ERROR, {
success: false,
message: 'Could not join class',
error: error.message,
});
}
});
socket.on('disconnect', async (reason) => {
const userId = socket.data.user.id;
const isStudent = socket.data.user.role.id === 3;
if (isStudent) {
const userData = await getUserDataUsingSocketId(socket.id);
if (userData) {
const studentId = userData.userId;
const classID = userData.classID;
if (studentId && classID) {
await handleStudentDisconnect(studentId, classID);
const students = await updateStudentList(classID);
this.io.to(classID).emit(socketConstants.UPDATE_STUDENT_LIST, students);
}
}
socket.data.isInTest = false;
}
});