ES6クラスのOOP環境でSocket.IOを実装する方法を知っている人がいますか?私がSocket.ioで実行し続ける主な問題は、私の場合「io」と呼ばれるサーバオブジェクトを回していることです。 socket.ioのほとんどすべての例は純粋なスパゲッティコードであり、ソケット関連のイベントやロジックがたくさんあるファイルです。最初に、サーバーオブジェクトioを新しいクラスのコンストラクタに渡そうとしましたが、なんらかの理由で「RangeError:最大呼び出しスタックサイズを超えました」というエラーメッセージが表示されます。次に、私のクラスをmodule.exports関数でラップしようとしましたが、そのパラメータにはioオブジェクトが含まれているはずです。ファーストクラスにはうれしいです。私がゲームにioオブジェクトを渡したとしましょう。期待どおりの素晴らしい作品です。しかし、ioオブジェクトをRoundクラスまで参照しようとすると(ゲームにはラウンドの配列が保持されます)、私はできません。これはNodeJSの悪い習慣の1つですので、requireはglobalでなければなりません。モジュール/関数の内部ではありません。だから私は再び同じ問題で戻ってきます。 (私はメインソケットファイルが必要です)Socket.io ES6クラス内の値
app.js
const io = socketio(server, { origins: '*:*' });
...
require('./sockets')(io);
(私は私のゲームサーバーを初期化し、クライアントソケットからの着信メッセージハンドル)
を
ソケット/ 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(ゲームのクラスによって使用されるES6クラス(私はconneに放出することができるよように、どのように私は私のクラスへのIOの参照を渡すことができます。質問に要約するラウンド配列))
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;
これらのクラス内にソケットを挿入しましたか? 必ずしもES6クラスである必要はありません。.prototypeプロパティを使用するNodeJSオブジェクトにすることができます。私はちょうどソケットと私のゲームサーバーを処理するmainatainable方法が欲しい...任意のヘルプが是認されています!