2017-04-05 13 views
0

Node.jsでモジュールを要求して使用する方法について少し混乱します。複数のモジュールでsocket.ioが必要(同じインスタンス)

私のシナリオは以下の通りです:

私は、リアルタイム通信にSocket.ioを使用して1つのファイルに完全なサーバーを書きました。

index.jsがかなり大きくなりました。コードを複数のモジュールに分割して管理しやすくしたいと考えています。

たとえば、クライアントに調査を提供し、回答を返すための機能がいくつかあります。私はこれらの関数をすべて別々のモジュールに入れ、index.jsにそれを必要とします。これまでのところうまく動作します。

唯一のことは、モジュール内でSAMEソケットインスタンスを使用する別の方法がある場合です。

私の現在のコードは次のようになります。

index.js:

var express = require('express'); 
var app = express(); 
var server = require('http').createServer(app); 
var io = require('socket.io')(server); 
var Survey = require('./survey'); 

io.on('connection', function (client) { 
    client.on('getCurrentQuestion', function (data) { 
     Survey.getCurrentQuestion(parseInt(data.survey_id), client.id); 
    }); 
}); 

server.listen(port, server_url, function() { 
    Survey.init(io); 
}); 

survey.js:

var io = null; 

var Survey = {}; 

Survey.init = function(socketio) { 
    io = socketio; 
}; 

Survey.getCurrentQuestion = function(survey_id, socket_id) { 
    var response = { 
     status: "unknown", 
     survey_id: survey_id 
    }; 

    // [...] some code that processes everything 

    // then uses Socket.io to push something back to the client 
    io.sockets.in(socket_id).emit('getCurrentQuestion', response); 
}; 

module.exports = Survey; 

それが動作します。この方法で、私はioを渡して満足していません必要なモジュールへのinit関数の内部にあります。

これを行うには "正しい方法"がありますか?

調査モジュール内のI require('socket.io')の場合は、index.jsと同じインスタンスになりますか?

index.jsで作成されたappが必要なserverが必要なので、どうすればいいでしょうか?

私は混乱しており、誰かが私を助けることを願っています。ありがとう!

答えて

1

node.JSライブラリをインポートすると、オブジェクトを渡すこともできます。あなたのケースではindex.jsファイルには、次のように変更します。

//index.js 
var express = require('express'); 
var app = express(); 
var server = require('http').createServer(app); 
var io = require('socket.io')(server); 
var Survey = require('./survey')(io); 

それからちょうどIOオブジェクト取るためにあなたのsurvey.jsコードを変更:あなたの他の質問に答えるために

//survey.js 

module.exports = function (io) { 
    var Survey = {}; 

    Survey.getCurrentQuestion = function(survey_id, socket_id) { 
     var response = { 
      status: "unknown", 
      survey_id: survey_id 
     }; 

     // [...] some code that processes everything 

     // then uses Socket.io to push something back to the client 
     io.sockets.in(socket_id).emit('getCurrentQuestion', response); 
    }; 

    return Survey; 
}; 

を:

調査モジュール内にrequire('socket.io')がある場合、index.jsとは異なるインスタンスになります。

EDIT

あなたがそれを行うためのより近代的な方法をしたい場合は...あなたはこれより良いを行うにはES6形式を使用してクラスを作成することができます。

'ES6 index.js 

import SurveyClass from './Survey'; 
import * as express from 'express'; 
let app = express(); 
let server = require('http').createServer(app); 
let io = require('socket.io')(server); 
let MySurveyClass= SurveyClass(io); 
let myInstance = new MySurveyClass(); 

myInstance.getCurrentQuestion(5, "some-socket-id"); 

'ES6 survey.js 
export default class Survey{ 

    constructor(io){ 
     this.io= io; 
    }; 


    getCurrentQuestion(survey_id, socket_id) { 
     var response = { 
      status: "unknown", 
      survey_id: survey_id 
     }; 

     // [...] some code that processes everything 

     // then uses Socket.io to push something back to the client 
     this.io.sockets.in(socket_id).emit('getCurrentQuestion', response); 
    }; 




} 
+0

どのように私はより多くを定義しますこの方法でサーベイモジュールの1つの機能ですか?現在のところ、 'Survey'には多くの関数を付けているので、' var Survey = {} 'と' module.exports = Survey'という論理があります。 – Danmoreng

+0

私はあなたが何を意味するかを見ます...病気の答えを更新します。 –

+0

実際に私の目には意味があります。しかし、ここでは、匿名のコンストラクター関数内でオブジェクトとしてSurveyを定義する代わりに、関数に名前が付けられ、Survey.prototype.loadSurvey = function(){}によって接続された他の関数がどこにあるのか、複数の例を見てきました。それは私のために働くようには思われません、なぜ私は分かりません。 :(例:https://codinginthetrenches.com/2015/10/03/nodejs-modules-should-export-object-constructors/ – Danmoreng

0

あなたは複数のモジュールでこれを行うと:

var socketio = require('socket.io'); 

すべてが必要となるため、同じオブジェクトになります。

しかし、あなたはこれを行う場合:

var io = require('socket.io')(server); 

あなたは両方の場所でserverで同じオブジェクトを持っている場合でも、それもrequire('socket.io')で返される機能の異なる呼び出しから来るので、ioは異なる値になりますそれらの機能は同じになります。

ioが同じであることを確認したい場合は、たとえば次のようにします。 ioという約束を出して、それを初期化する何らかの方法で、serverと必要なものをすべて取得する関数を作るモジュールを作ってください。さて、serverがある場所で、モジュールを要求し、そのエクスポートされた関数で初期化することができます。他の場所では、モジュールをインポートして約束を使用することができます。

コールバックや、初期には定義されていない可能性のあるエクスポートされたオブジェクトのプロパティだけでなく、socket.ioが初期化されたときに定義されるプロパティも使用できますが、約束を使用すると、まだ準備が整っていない間は、あなたはそれを使用していません。

フレームワークを使用するかどうか、Hapiのようなフレームワークの中には、そのような機能を簡単に共有するためのフレームワークを使用するかどうかという質問はありませんでした。例えば。参照:

あなたはハピを使用する場合は、あなたがプラグインを使用する必要があります。他のフレームワークで同様の機能を検索する場合