2014-09-02 41 views
8

我一直在嘗試創建(基本上)一個工廠函數,爲我所擁有的十幾個小型專用服務器配置和構建一個expressjs服務器。對於這部分我想增加聽功能。我如何重載app.listen的功能expressjs

我想知道最好的方法去做這件事。我也在這裏尋找可重複使用的設計選擇。

服務器是否正常創建:

var httpServer = express(); 
    ... 

的因爲快遞的設計方式(不知道如果我是正確的),我不能訪問任何{} .prototype.listen。所以我想出了兩種方法。

在當前範圍內使用一個額外的變量:

var oldListen = httpServer.listen; 
httpServer.listen = function(callback){ 
    ... 
    oldListen.call(httpServer, options.port, options.host, function(){ 
     ... 
     if (typeof callback == 'function') callback();      
    }); 
}; 

其中一期工程,是相當簡單的,但後來我有一個可變的提升疣。我也有一個封閉的解決方案,但我認爲這可能是太遲鈍了非常實用:

httpServer.listen = (function(superListen){ 
    return function(callback){ 
     ... 
     superListen.call(httpServer, options.port, options.host, function(){ 
     ...    
     if (typeof callback == 'function') callback(); 
     }); 
    };            
})(httpServer.listen); 

兩個例子是工廠上下文的一部分,我故意減少傳遞給函數的參數。

任何幫助,將不勝感激。

+0

Express中間件依賴於訂單,所以工廠函數可能會咬你。你可以編寫中間件,以在每個應用程序中需要更少的東西https://gist.github.com/aj0strow/b0a1232d2f0df54e1a13 – AJcodez 2014-12-30 06:33:37

回答

1

您應該可以輕鬆地重載快速監聽功能。您可以在下面的對象路徑訪問它:express.application.listen

所以,可以實現這樣的事情:

var express = require('express'); 

express.application.baseListen = express.application.listen; 
express.application.listen = function(port) { 
console.log('Port is: ' + port); 
    this.baseListen(port); 
}; 

監聽功能的實現是在快遞模塊文件夾下的以下路徑:node_modules\express\lib\application.js

-1

綁定並偵聽給定主機和端口上的連接。此方法與節點的http.Server#listen()相同。

var express = require('express'); 
var app = express(); 
app.listen(3000); 

快遞()返回該應用程序實際上是一個JavaScript功能,設計被傳遞到節點的HTTP服務器作爲一個回調來處理請求。這使您可以提供相同的代碼庫您的應用程序的HTTP和HTTPS版本很容易,因爲應用程序不會從這些繼承(這是一個簡單的回調):

var express = require('express'); 
var https = require('https'); 
var http = require('http'); 
var app = express(); 

http.createServer(app).listen(80); 
https.createServer(options, app).listen(443); 

的app.listen()方法以下一個簡便方法(如果你想使用HTTPS或同時提供,使用上述技術):

app.listen = function(){ 
var server = http.createServer(this); 
return server.listen.apply(server, arguments); 
}; 

參考http://expressjs.com/api.html

希望這有助於。

2

如果你堅持「超載」,確保你實現了原來的足跡(這就是超載的性質)。快速listen只是一個別名節點的internal http listen method

server.listen(port, [host], [backlog], [callback]); 

UPDATE:快遞甚至建議使用自定義實現節點的服務器API:http://expressjs.com/4x/api.html#app.listen

否則,您應該創建自己的自定義listen方法,這將是定義爲:

httpServer.myCustomListen = function (callback) { 
    httpServer.listen.call(httpServer, options.port, options.host, callback); 
} 

第二個選項是你最好的選擇,但爲了它的工作,你必須擴展expre ss庫。 Express是開放源代碼並託管在Github上。將它叉起來並隨意修改。定期在新更新中更新pull,以便與核心庫保持同步。我一直用節點模塊來做這件事。

有來自做這種方式有兩個好處:

  1. 您可以完全控制自定義代碼,但是你認爲合適而保持最新與原作者寫的代碼。

  2. 如果您發現錯誤或構建了一個很酷的功能,您可以提交拉取請求以使整個社區受益。

你會先用叉子叉庫,然後抓住網址爲你的叉子,克隆它,然後添加一個參照原來的「上游」回購:

git clone [url_to your_fork] 
cd express 
git remote add upstream [email protected]:strongloop/express.git 

然後你就可以將更改推送到您自己的回購(git push)。如果您想從原始回購中獲取更新,可以從上游回購:git pull upstream master

如果你想添加的表達您的自定義叉子作爲NPM模塊爲一個項目,你可以使用下列內容:

npm install git://github.com/[your_user_name]/express.git --save 
2

維克多的答覆中指出,快速的原型是express/lib/application.js。該文件用於構建express,並通過express/lib/express.js中的application名稱空間導出。因此,可以使用express.appliction.listen來引用.listen函數。

人們可以使用這個方法,那麼:(類似於維克多的方法)

var express = require('express'); 

express.application._listen = express.application.listen; 
express.application.listen = function(callback) { 
    return this._listen(options.port, options.host, callback); 
}; 

人們也可以使用羅儀表板的_.wrap功能,如果你不想基函數存儲在一個變量自己。這將是這個樣子:

var express = require('express'); 
var _ = require('lodash'); 

express.application.listen = _.wrap(express.application.listen, function(listenFn) { 
    return listenFn(options.port, options.host, callback); // Called with the same this 
}; 

但是,使用這些方法會遇到你在你的問題中提到的問題(可變懸掛,創建一個額外的變量)。爲了解決這個問題,我通常會創建我自己的子類express.application並替換該子類中的.listen函數,並告訴express使用該子類。但是,由於express的當前結構,您不能用您自己的子類替換express.application而不覆蓋express()函數本身。

因此,我要做的是完全接管express.application.listen,因爲它只有2行。這很簡單!

var express = require('express'); 
var http = require('http'); 

express.application.listen = function(callback) { 
    return http.createServer(this).listen(options.port, options.host, callback); 
}; 

你甚至可以做一個https選項!

var express = require('express'); 
var http = require('http'); 
var https = require('https'); 

express.application.listen = function(callback) { 
    return (options.https ? http.createServer(this) : https.createServer({ ... }, this)) 
      .listen(options.port, options.host, callback); 
}; 

注意:其他答案之一提到分叉表達和修改它。對於這樣一個小功能,我會有一段艱難的時間。