从客户端到所有房间的发射功能一次,socket.io
我是socket.io的新手,很难弄清楚如何正确使用服务器和客户端。因此,我的客户端有一个功能,可以倾听服务器以获取一系列问题以将其显示到房间。
这个想法是创建一个与几个客户连接的客户建立房间,并从客户端发射一个函数(只有一次,我想向所有房间显示信息)。我确实需要在客户端的功能,因为我有大约100行与正面有关的代码。另外,我的服务器需要将其数组发射给客户端。 我的问题是,由于它是客户端,因此当我将其发射到服务器上时,它将发射X乘以房间内的客户端数量。我希望只发出一次。
要有一个具体的示例:我的服务器具有一个数组对象,该对象将传递给房间中的客户端,以便它们可以显示。这是客户端中的函数:
//I have shorten the function so it is not too much but you can still grasp how I need it in my client
socket.on('getNewQuestion', (currentQuestion) => {
init();
questionNumber.innerHTML = "Question " + countQuestion;
questionParams.id = currentQuestion.questionId;
questionParams.questionTxt = currentQuestion.question;
questionParams.reponse = JSON.parse(currentQuestion.reponse);
questionParams.lien = currentQuestion.lien;
questionParams.type = currentQuestion.type;
//Display question text
questionTxt.innerHTML = currentQuestion.question;
//Display different informations according to the question's type
switch (currentQuestion.type) {
case "enigme":
var getReponseLength = JSON.parse(currentQuestion.reponse)[0].length;
questionType.innerHTML = "find the answer to this question with " + getReponseLength + " letters";
break;
case "anagramme":
questionType.innerHTML = "find a word usign all these letters :";
const html = [];
//Parse string to create array of chars
var questionParse = JSON.parse(currentQuestion.question);
//Gets the characters of the string and shuffles it
for (let i = questionParse.length - 1; i >= 0; i--) {
const randLetters = Math.floor(Math.random() * (i + 1));
[questionParse[i], questionParse[randLetters]] = [questionParse[randLetters], questionParse[i]];
html.push(`<div>${questionParse[i]}</div>`);//display letter
}
currentQuestion.question = questionParse;
questionTxt.innerHTML = html.join(" ");
break;
}
countQuestion++;
});
然后我在服务器中发出它以获取问题对象,
socket.on('callGetNewQuestion', (roomCode) => {
//Get a random question from the object
const questionCalled = questions.getQuestionsList(roomCode)[Math.floor(Math.random() * questions.getQuestionsList(roomCode).length)];
io.in(roomCode).emit('getNewQuestion', questionCalled); //emit the random question to the client
questions.removeQuestion(questionCalled.questionId); //remove it so it doesn't appear twice
});
并且我在客户端中发出(我不确定这是好的练习,但我对如何如何了解否则请收听对象)
socket.on('startGame', () => {
socket.emit('callGetNewQuestion', userParams.roomCode);
timerCountdownGame();
});
此代码的问题是:正如从客户端调用的那样,如果房间中有两个客户,则称为两次,如果有三个客户端,则称为三次,因此我开始游戏将从问题1传递到问题3(如果数量客户是三个)。 我希望我的意思是有道理的,如果不犹豫,
有人知道我如何纠正它吗?
I am a newbie with socket.io and I have a hard time figuring out how to correctly use server and client. So, I have a function on my client side that listens to the server to get an array of questions to display it to the room.
The idea is to create a room with several clients connected, and to emit to one room a function from the client side (only once, as I want to display the information to all the room). I really need this function on my client side as I have approximately 100 lines of code that concerns the front. Also my server needs to emit its array to the client.
My problem is, since it is client side, when I emit it to the server it will be emitted x times the number of clients inside the room. And I wish to emit it only once.
To have a concrete example : My server has an object of array which is passed to the clients in a room so they can display it. Here is the function in the client :
//I have shorten the function so it is not too much but you can still grasp how I need it in my client
socket.on('getNewQuestion', (currentQuestion) => {
init();
questionNumber.innerHTML = "Question " + countQuestion;
questionParams.id = currentQuestion.questionId;
questionParams.questionTxt = currentQuestion.question;
questionParams.reponse = JSON.parse(currentQuestion.reponse);
questionParams.lien = currentQuestion.lien;
questionParams.type = currentQuestion.type;
//Display question text
questionTxt.innerHTML = currentQuestion.question;
//Display different informations according to the question's type
switch (currentQuestion.type) {
case "enigme":
var getReponseLength = JSON.parse(currentQuestion.reponse)[0].length;
questionType.innerHTML = "find the answer to this question with " + getReponseLength + " letters";
break;
case "anagramme":
questionType.innerHTML = "find a word usign all these letters :";
const html = [];
//Parse string to create array of chars
var questionParse = JSON.parse(currentQuestion.question);
//Gets the characters of the string and shuffles it
for (let i = questionParse.length - 1; i >= 0; i--) {
const randLetters = Math.floor(Math.random() * (i + 1));
[questionParse[i], questionParse[randLetters]] = [questionParse[randLetters], questionParse[i]];
html.push(`<div>${questionParse[i]}</div>`);//display letter
}
currentQuestion.question = questionParse;
questionTxt.innerHTML = html.join(" ");
break;
}
countQuestion++;
});
Then I emit it in my server to get the object of question
socket.on('callGetNewQuestion', (roomCode) => {
//Get a random question from the object
const questionCalled = questions.getQuestionsList(roomCode)[Math.floor(Math.random() * questions.getQuestionsList(roomCode).length)];
io.in(roomCode).emit('getNewQuestion', questionCalled); //emit the random question to the client
questions.removeQuestion(questionCalled.questionId); //remove it so it doesn't appear twice
});
And I am emitting back in my client (which I am not sure if it is good practice but I don't have any idea on how to listen to the object otherwise)
socket.on('startGame', () => {
socket.emit('callGetNewQuestion', userParams.roomCode);
timerCountdownGame();
});
The problem with this code is : as it is called from the client side, if there is two clients in the room it is called twice, if there are three clients, it is called three times, so when I start the game it will pass from question 1 to question 3 (if number of clients is three).
I hope what I am saying makes sense, if not do not hesitate to tell me
Does anyone know how I can correct it ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您遇到的主要问题是服务器行为是由客户端驱动的,这应该是相反的...
为什么您的客户要求新问题?您的服务器应随时发送新问题。如果您真的需要提出客户请求问题,则应将当前问题存储在房间中,并发送当前问题,而不是生成它。
我认为您的房间应该保持某种状态,例如游戏开始,等待客户等...客户都准备好了,一旦所有客户准备就绪,就会生成问题并将其发送给所有客户。像这样。
The main problem you are having is that the server behaviour is driven by the client, which should be the opposite...
Why should your client request a new question? Your server should send the new question whenever it is available. If really you need to have your client request question, you should store the current question in your room and send the currentQuestion, not generate it.
I think your room should keep some state, like game started, waiting for clients etc... Clients all send a ready, once all clients are ready room generates a question and sends it to all clients. Something like so.