javascript - NodeJS,SocketIO IO发出功能不起作用
问题描述
tldr:SocketIO io 功能不起作用。
所以我正在开发一个使用 websockets 的游戏/网站,这样玩家就可以在解决一些问题时相互竞争。
我目前在一个文件中有与 socketIO 相关的代码,以便更容易设置测试,“webserver.js”如下所示:
const socketIO = require('socket.io');
const {
addPlayerToQueue,
removePlayerFromQueue,
} = require('./matchmakingFunctions/playerQueue');
const { matchmake } = require('./matchmakingFunctions/matchmake');
const {
questionSelect,
chooseQuestions,
chooseQuestionAlt,
} = require('./gameFunctions/questionSelect');
/**
* Initializes main io websocket connection
*
* @param {http.server} httpServerToBind - http server
*/
function socketServer(httpServerToBind) {
const io = socketIO(httpServerToBind);
io.on('connection', (socket) => {
// Begin matchmaking for the selected player
socket.on('matchmake', (player) => matchmake(io, socket, player));
... (Skipping some of the socket functions for clarity)
socket.on('newTest', async () => {
console.log('Inside newTest');
});
// When user disconnects (refreshes page, goes to another route), leave the queue
socket.on('disconnect', () => removePlayerFromQueue('', socket));
});
return io;
}
module.exports = socketServer;
但是,我试图让玩家“选择问题”时,最后我们会向两个玩家的套接字发出一个事件。例如,我目前有一个 mocha 测试,设置如下:
...
const wsClient = require('socket.io-client');
const wsServer = require('../webServer');
...
describe('Question Selection', function beginTests() {
let user1;
let user2;
let user3;
let server;
let io;
before(async function connectServer() {
[user1, user2, user3] = userMockData;
server = http.createServer();
io = wsServer(server);
await databaseConnection();
await Promise.all([Match.deleteMany({}), User.deleteMany({})]);
user1 = await user1.save();
user2 = await user2.save();
user3 = await user3.save();
await server.listen(port);
});
afterEach(async function cleanServer() {
await Match.deleteMany({});
});
after(async function disconnectServer() {
io.sockets.sockets.forEach((socket) => {
socket.disconnect();
});
await Promise.all([io.close(), mongoose.disconnect()]);
});
在这里,我正在运行一个测试来连接两个用户,让他们匹配,让他们选择他们想要使用的问题,然后向他们发送一个事件,告诉他们我们正在从问题选择转向游戏玩法。除了我遇到问题的最后一部分设置之外,我拥有一切。当前代码如下:
it('Shift to Gameplay', function (done) {
this.timeout(20000);
const timeEpsilon = 9000;
let client1;
let client2;
const interval = setInterval(async () => {
// Get the earliest event that was made and process
const earliestEvent = await Match.findOne({
$or: [{ status: 'Question-Selection' }, { status: 'In-Match' }],
}).sort('-updatedAt');
if (earliestEvent) {
// Process the event
let timeToFinishTask = dayjs(earliestEvent.updatedAt);
timeToFinishTask = timeToFinishTask.add(timeEpsilon, 'ms');
const now = dayjs();
if (earliestEvent.status === 'Question-Selection') {
if (
earliestEvent.player1.problems.length === 3 &&
earliestEvent.player2.problems.length === 3
) {
earliestEvent.status = 'In-Match';
io.socket.to(earliestEvent.player1.socket).emit('newTest', {});
await earliestEvent.save();
done();
} else if (timeToFinishTask <= now) {
io.to(matchSettings.player1.socket).emit('newTest');
}
} else if (earliestEvent.status === 'In-Match') {
}
}
}, 1000);
client1 = wsClient.connect(socketURL, options);
client1.on('connect', () => {
client1.emit('addPlayer', { user: user1, gamemode: 'test' });
});
// Player1 connected, try to connect Player2
client1.on('addedPlayer', () => {
client2 = wsClient.connect(socketURL, options);
client2.on('connect', () => {
client2.emit('addPlayer', { user: user2, gamemode: 'test' });
client2.on('addedPlayer', (player2) => {
// Player2 connected, matchmake them
client2.emit('matchmake', player2._id);
client2.on('matchmade', async (matchSettings) => {
assert(matchSettings.player1.userId === user2._id.toString());
assert(matchSettings.player2.userId === user1._id.toString());
// Get the questions from the database
client2.emit('questionSelect', { matchSettings: matchSettings });
// Get the questions pool back from the database
client2.on('QuestionPool', (questionPoolPlayer2) => {
client1.on('QuestionPool', (questionPoolPlayer1) => {
assert(questionPoolPlayer1);
assert(questionPoolPlayer2);
assert(questionPoolPlayer1 !== questionPoolPlayer2);
client1.emit('chooseQuestionAlt', {
user: user1,
questions: [],
questionPool: questionPoolPlayer1,
});
client2.emit('chooseQuestionAlt', {
user: user2,
questions: [
questionPoolPlayer2[0],
questionPoolPlayer2[1],
questionPoolPlayer2[2],
],
questionPool: questionPoolPlayer2,
});
client1.on('questionsSavedAlt', (newMatchSettings1) => {});
client2.on('questionsSavedAlt', (newMatchSettings2) => {});
});
});
});
});
});
});
});
});
在 setInterval 函数中可以看到主要错误的一个示例。我有一个 io.to(matchSettings.player1.socket).emit() (matchsettings 文档存储了播放器的 socketid 以供以后参考),但是它永远不会被调用,因为控制台永远不会记录事件内部的字符串。在两个播放器在回调内连接后,我尝试过这样做,但这也失败了。我试过 io.to().emit() 和 io.emit(),但它不起作用。
我不能依赖客户端套接字,因为此信息在后端处理,然后发送到前端,前端输入不多。如果我遗漏了什么,或者如果有更好的方法可以做到这一点,我们将不胜感激。谢谢你。
解决方案
推荐阅读
- sql - Oracle 11G DB:在 where 子句中使用视图时,视图中“clob”类型列的结果发生了变化
- python - 在 python 中替代 eval 以从 dat 文件中读取输入
- c# - 如何验证一个字段取决于 asp .net core 6.0 中的另一个字段
- python - 如何修复请求异常 ConnectionError
- security - k8s中对服务请求的身份验证
- flutter - 转换为日期时间格式,小时、分钟和秒分开
- html - 当用户在输入字段中输入以逗号分隔的值时。如何以列表格式显示输出
- r - 使用 R 中的 plot_geo 将标签添加到伊朗地图的省份
- c# - SQL插入语句,没有错误或异常,但没有插入数据
- ros - 启动多个机器人的问题