2017-11-17 16 views
0

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方法が欲しい...任意のヘルプが是認されています!

答えて

関連する問題