gpt4 book ai didi

javascript - Socket.io 在 ES6 类中发出值

转载 作者:行者123 更新时间:2023-12-03 03:01:58 26 4
gpt4 key购买 nike

我想知道是否有聪明的人可以告诉我如何在 OOP 环境中使用 ES6 类实现 Socket.IO。我在使用 Socket.io 时遇到的主要问题是传递服务器对象,在我的例子中称为“io”。我见过的几乎每个 socket.io 示例都是纯粹的意大利面条式代码,一个文件包含许多与套接字相关的事件和逻辑。首先,我尝试将服务器对象 io 传递给新类的构造函数,但由于某种原因,您最终会收到令人讨厌的“RangeError:超出最大调用堆栈大小”错误消息。然后我尝试将我的类包装在 module.exports 函数中,该函数的参数应包含 io 对象。对于头等舱来说这很好。假设我将 io 对象传递到我的游戏中,效果如预期的那样出色。但是当我尝试将 io 对象引用到 Round 类时(Game 包含 Rounds 数组),我不能这样做。因为这是 NodeJS 中一种糟糕的做法,所以 require 应该是全局的,而不是在模块/函数内部。所以我再次遇到同样的问题。

app.js(我需要主套接字文件)

const io = socketio(server, { origins: '*:*' });
...
require('./sockets')(io);

sockets/index.js(我在其中初始化游戏服务器,并处理来自客户端套接字的传入消息)

const actions = require('../actions.js');
const chatSockets = require('./chat-sockets');
const climbServer = require('./climb-server');
const authFunctions = require('../auth-functions');

module.exports = (io) => {
io.on('connection', (client) => {
console.log('client connected...');
// Standard join, verify the requested room; if it exists let the client join it.
client.on('join', (data) => {
console.log(data);
console.log(`User ${data.username} tries to join ${data.room}`);
console.log(`Client joined ${data.room}`);
client.join(data.room);
});

client.on('disconnect', () => {
console.log('Client disconnected');
});

client.on(actions.CREATE_GAME, (hostParticipant) => {
console.log('CREATE_GAME', hostParticipant);

// Authorize socket sender by token?
// Create a new game, and set the host to the host participant
climbServer.createGame(io, hostParticipant);
});

client.on(actions.JOIN_GAME, (tokenizedGameId) => {
console.log('JOIN_GAME');

const user = authFunctions.getPayload(tokenizedGameId.token);

// Authorize socket sender by token?
// Create a new game, and set the host to the host participant
const game = climbServer.findGame(tokenizedGameId.content);
game.joinGame(user);
});
});
};

climbServer.js(我的游戏服务器,用于跟踪事件游戏)

const actions = require('../actions.js');
const Game = require('../models/game');

const climbServer = { games: { }, gameCount: 0 };

climbServer.createGame = (io, hostParticipant) => {
// Create a new game instance
const newGame = new Game(hostParticipant);
console.log('New game object created', newGame);

// Store it in the list of game
climbServer.games[newGame.id] = newGame;

// Keep track
climbServer.gameCount += 1;

// Notify clients that a new game was created
io.sockets.in('climb').emit(actions.CLIMB_GAME_CREATED, newGame);
};

climbServer.findGame = gameId => climbServer.games[gameId];

module.exports = climbServer;

Game.js(应该能够向所有连接的套接字发出信号的 ES6 类)

const UUID = require('uuid');
const Round = require('./round');

class Game {
// Constructor
constructor(hostParticipant) {
this.id = UUID();
this.playerHost = hostParticipant;
this.playerClient = null;
this.playerCount = 1;
this.rounds = [];
this.timestamp = Date.now();
}

joinGame(clientParticipant) {
console.log('Joining game', clientParticipant);
this.playerClient = clientParticipant;
this.playerCount += 1;

// Start the game by creating the first round
return this.createRound();
}

createRound() {
console.log('Creating new round at Game: ', this.id);
const newRound = new Round(this.id);

return this.rounds.push(newRound);
}
}

module.exports = Game;

Round.js(Game类使用的ES6类(存储在rounds数组中))

const actions = require('../actions.js');

class Round {
constructor(gameId) {
console.log('Initializing round of gameId', gameId);
this.timeLeft = 60;
this.gameId = gameId;
this.winner = null;
this.timestamp = Date.now();

// Start countdown when class is instantiated
this.startCountdown();
}

startCountdown() {
const countdown = setInterval(() => {
// broadcast to every client
io.sockets.in(this.gameId).emit(actions.ROUND_TIMER, { gameId: this.gameId, timeLeft: this.timeLeft });
if (this.timeLeft === 0) {
// when no time left, stop counting down
clearInterval(countdown);
this.onRoundEnd();
} else {
// Countdown
this.timeLeft -= 1;
console.log('Countdown', this.timeLeft);
}
}, 1000);
}

onRoundEnd() {
// Evaluate who won
console.log('onRoundEnd: ', this.gameId);
}
}

module.exports = Round;

总结一个问题:如何将 io 的引用传递给我的类,以便我能够向这些类中连接的套接字发出信号?这不一定是 ES6 类,它可以是使用 .prototype 属性的 NodeJS 对象。我只是想要一种可维护的方式来使用套接字处理我的游戏服务器...感谢任何帮助!

最佳答案

经过几个小时的努力,我找到了一个解决方案。如果有人遇到同样的事情,请查看下面我的解决方案。不是最好的,但比将所有套接字相关代码放在一个文件中要好得多......

Game.js(ES6 类)。关注包含“module.exports”的第一行。

const GameFactory = require('../models/game');

const climbServer = { games: { }, gameCount: 0 };

climbServer.createGame = (io, hostParticipant) => {
// Create a new game instance
const Game = GameFactory(io);
const newGame = new Game(hostParticipant);
console.log('New game object created', newGame);

// Store it in the list of game
climbServer.games[newGame.id] = newGame;

// Keep track
climbServer.gameCount += 1;

return newGame;
};

climbServer.findGame = gameId => climbServer.games[gameId];

module.exports = climbServer;

诀窍是在您首先声明的地方使用此工厂模式:

const GameFactory = require('../models/game');

然后通过传入 Socket.io 服务器对象(在我的例子中为“io”)来初始化工厂。如果您通过构造函数传递它,您最终会得到 RangeError,因此这是唯一的方法。再次不确定此代码与意大利面条代码相比的性能如何。

const Game = GameFactory(io);

最后,您现在可以实例化类的实例:

const newGame = new Game(hostParticipant);

如果有人有改进或想法,请给我留言。仍然不确定这段代码的质量。

关于javascript - Socket.io 在 ES6 类中发出值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47341491/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com