2017-04-05 77 views
0

我有點困惑,關於如何在Node.js中要求和使用模塊。在多個模塊中要求(同一個實例)socket.io

我的情況是這樣的:

我在一個單一的文件,它使用Socket.io實時通信寫了一個完整的服務器。

現在,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函數中。

什麼是「正確的方法」來做到這一點?

如果我在require('socket.io')裏面的調查模塊中,它是否與index.js中的實例相同?

我怎麼會要求,因爲它需要server,它需要app,這是在index.js創建?

我很困惑,希望有人能幫助我。謝謝!

回答

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); 

然後,只需改變你的survey.js代碼採取IO對象:

//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不同的實例。

編輯

如果你想要做的更現代的方式。你可以使用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

我怎麼會定義一個以上調查模塊中的一個功能是這樣的嗎?目前邏輯是'var Survey = {}'和'module.exports = Survey',因爲我將許多函數附加到'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同一個對象,io將是一個不同的值,因爲它會來從require('socket.io')返回的功能的不同調用甚至儘管這些功能將是相同的。

如果你想確保io是相同的,那麼你應該做的例如像這樣:做一個模塊,輸出io的承諾和一些方法來初始化它 - 一個函數,獲取server和所需的一切。現在,在您有server的地方,您可以要求該模塊並使用該導出的函數對其進行初始化,並且在其他地方您可以導入該模塊並使用承諾。

而不是一個承諾,你可以使用回調,甚至只是一個導出對象的屬性,可能最初是未定義的,並在socket.io初始化時定義,但使用承諾可能是最簡單的解決方案,以確保當它還沒有準備好時,你還沒有使用它。

你沒有在你的問題提你是否使用了一些框架和其中一個如果有的話,但一些喜歡哈皮的框架,給你一個簡單的方法來這樣的共享功能。例如。見:

如果使用哈皮那麼你應該使用的插件。如果其他框架然後搜索相似的功能。

相關問題