2014-09-02 3 views
8

Ho cercato di creare (fondamentalmente) una funzione di fabbrica che configura e costruisce un server expressjs per una dozzina di server specializzati più piccoli che ho. Per parte di questo voglio aumentare la funzione di ascolto.Come sovraccarico la funzionalità di app.listen in expressjs

Mi piacerebbe sapere qual è il modo migliore per farlo. Sto anche cercando una scelta di design riutilizzabile qui.

Server viene creato normalmente:

var httpServer = express(); 
    ... 

A causa del modo esplicito è stato progettato (non so se ho ragione) Non è possibile accedere a {} qualunque .prototype.listen. Quindi ho inventato due approcci.

Utilizzando una variabile aggiuntiva nell'ambito corrente:

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

Che funziona ed è abbastanza semplice, ma poi ho una verruca sollevamento variabile. Ho anche una soluzione di chiusura, ma penso che potrebbe essere troppo ottuso per essere pratico:

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

Entrambi gli esempi sono parte del contesto in fabbrica e sto volutamente riducendo gli argomenti passati alla funzione.

Qualsiasi aiuto sarebbe apprezzato.

+0

Il middleware espresso dipende dall'ordine, quindi è probabile che una funzione di fabbrica ti morda. Puoi comporre il middleware per richiedere meno cose in ogni app https://gist.github.com/aj0strow/b0a1232d2f0df54e1a13 – AJcodez

risposta

1

Si dovrebbe essere in grado di sovraccaricare facilmente la funzione di ascolto rapido. È possibile accedere nel seguente percorso Oggetto: express.application.listen

Quindi, è possibile implementare qualcosa di simile:

var express = require('express'); 

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

L'implementazione della funzione di ascolto è nel seguente percorso nella cartella del modulo espresso: node_modules\express\lib\application.js

-1

Associare e ascoltare le connessioni sull'host e sulla porta specificati. Questo metodo è identico al nodo http.Server # listen().

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

L'applicazione restituito da espresso() è in realtà una funzione JavaScript, progettato per essere passato al server HTTP del nodo come un callback per gestire le richieste. Ciò consente di fornire entrambe le versioni HTTP e HTTPS della tua app con la stessa base di codice facilmente, come l'applicazione non eredita da questi (si tratta semplicemente di un callback):

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

L'app.listen() metodo è un metodo comodo per la seguente (se si desidera utilizzare HTTPS o fornire sia, utilizzare la tecnica di cui sopra):

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

Riferimento: http://expressjs.com/api.html

Spero che questo aiuti.

2

Se si insiste su "overloading", assicurarsi di implementare l'impronta originale (ad esempio la natura del sovraccarico).Esprimere listen è solo un alias a nodo internal http listen method:

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

UPDATE: espresso suggerisce anche utilizzando API del server di nodo per implementazioni personalizzate: http://expressjs.com/4x/api.html#app.listen

In caso contrario, si dovrebbe creare il proprio metodo personalizzato listen che sarebbe definito come:

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

La seconda opzione è la soluzione migliore, ma per poter funzionare, è necessario estendere l'expre libreria ss. Express è open source e ospitato su Github. Forcela e modificala come preferisci. Periodicamente pull in nuovi aggiornamenti in modo da rimanere aggiornati con la libreria principale. Lo faccio sempre con i moduli nodo.

Ci sono due benefici da fare in questo modo:

  1. Hai il controllo completo per personalizzare il codice tuttavia si vede in forma durante il soggiorno in regola con il codice scritto dagli autori originali.

  2. Se si trova un bug o costruire una caratteristica fredda, è possibile inviare una richiesta di pull a beneficio della comunità in generale.

Si potrebbe primo bivio il repository, poi prendete l'URL per forcella, clonarlo, e quindi aggiungere un riferimento a quello originale di pronti contro termine "a monte":

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

allora si può spingere le modifiche al proprio repository (git push). Se si desidera ottenere gli aggiornamenti dal repository originale, è possibile tirare dal repo monte: git pull upstream master.

Se vuoi aggiungere la forcella personalizzato di espressa come un modulo NPM per un progetto, è necessario utilizzare il seguente:

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

Come risposta di Victor ha sottolineato, il prototipo di espresso è in express/lib/application.js. Questo file è usato per costruire espresso e viene esportato attraverso il application namespace in express/lib/express.js. Pertanto, la funzione .listen possibile fare riferimento utilizzando express.appliction.listen.

Si può utilizzare questo metodo, allora: (simile al metodo di Victor)

var express = require('express'); 

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

Si può anche utilizzare la funzione di Lo-dash _.wrap se non si desidera memorizzare la funzione di base in una variabile da soli. Sarebbe simile a questa:

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

Tuttavia, l'utilizzo di questi metodi potrebbe incorrere in problemi che lei ha citato nella sua interrogazione (sollevamento variabile, la creazione di una variabile in più). Per risolvere questo problema, Io di solito creare il mio sottoclasse di express.application e sostituire la funzione .listen in quella sottoclasse e Tell Express di utilizzare tale sottoclasse invece. A causa di esprimere la struttura attuale, tuttavia, non è possibile sostituire il express.application con il proprio sottoclasse senza sostituire la funzione express() stesso.

Quindi, quello che vorrei fare è prendere in carico express.application.listen completamente poiché è solo 2 linee. È piuttosto semplice!

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

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

Si può anche fare un'opzione 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); 
}; 

Nota: una delle altre risposte indica biforcazione espressa e modifica. Avrei difficoltà a giustificarlo per una funzione così piccola.

Problemi correlati