2012-03-29 13 views
15

Ich schreibe eine Webanwendung in node.js. Nun ist jede Verarbeitung auf dem Server immer im Kontext einer Sitzung, die entweder abgerufen oder in der allerersten Stufe erstellt wird, wenn die Anforderung den Server erreicht. Danach durchläuft die Ausführung mehrere Module und Callbacks in ihnen. Worum ich mich bemühe, ist das Erstellen eines Programmiermusters, so dass an jedem Punkt im Code das Session-Objekt verfügbar ist, ohne dass der Programmierer es als Argument in jedem Funktionsaufruf übergeben muss.Node.js Programmierungsmuster zum Abrufen des Ausführungskontexts

Wenn der gesamte Code in einer einzigen Datei war, hätte ich eine Schließung haben können, aber wenn Funktionsaufrufe zu anderen Modulen in anderen Dateien sind, wie programmiere ich, so dass das Sitzungsobjekt in der aufgerufenen Funktion verfügbar ist als ein Argument. Ich denke, es sollte eine Verbindung zwischen den zwei Funktionen in den zwei Dateien geben, aber wie man das arrangiert, ist, wo ich stecken bleibe.

Im Allgemeinen möchte ich sagen, dass es immer einen Ausführungskontext gibt, der eine Sitzung oder eine Netzwerkanforderung sein kann, deren Verarbeitung über mehrere Dateien verteilt ist und das Ausführungskontextobjekt an allen Stellen verfügbar gemacht werden soll. Es kann mehrere Anwendungsfälle geben, beispielsweise ein Log-Objekt für jede Netzwerkanforderung oder ein Log-Objekt pro Sitzung. Und die für diese Arbeit erforderlichen Rohrleitungen sollten seitlich angebracht werden, ohne dass sich der Anwendungsprogrammierer darum kümmern muss. Er weiß nur, dass dieser Ausführungskontext überall verfügbar ist.

Ich denke, es sollte ziemlich allgemeines Problem von allen konfrontiert werden, also bitte geben Sie mir einige Ideen.

Es folgt das Problem

MainServer.js 


    app = require('express').createServer(); 
    app_module1 = require('AppModule1'); 
    var session = get_session(); 
    app.get('/my/page', app_module1.func1); 

AppModule1.js 

    app_module2 = require('AppModule2'); 
    exports.func1 = function(req,res){ 

    // I want to know which the session context this code is running for 

    app_module2.func2(req,res); 

    } 

AppModule2.js 

    exports.func2 = function(req,res){ 

    // I want to know where the session context in which this code is running 

    } 
+1

Wenn Sie eine Möglichkeit, dies zu tun herausgefunden, geben Sie bitte Ihre eigene Frage zu beantworten. –

Antwort

8

Sie können dies mit Domains erreichen - ein neues Merkmal von Knoten 0.8. Die Idee besteht darin, jede Anforderung in ihrer eigenen Domäne auszuführen und Speicherplatz für Daten pro Anforderung bereitzustellen. Sie können zur Domäne der aktuellen Anfrage gelangen, ohne sie über process.domain übergeben zu müssen. Hier

ist ein Beispiel dafür Setup immer mit Express zu arbeiten: How to use Node.js 0.8.x domains with express?

Beachten Sie, dass im Allgemeinen sind Domänen etwas experimentell und process.domain insbesondere nicht dokumentiert ist (wenn auch offenbar nicht weg in 0,8, und es gibt einige Diskussionen darüber, es dauerhaft zu machen). Ich schlage vor, ihrer Empfehlung zu folgen und eine app-spezifische Eigenschaft zu process.domain.data hinzuzufügen.

https://github.com/joyent/node/issues/3733

https://groups.google.com/d/msg/nodejs-dev/gBpJeQr0fWM/-y7fzzRMYBcJ

0

Da Sie Express verwenden, können Sie Sitzung auf jede Anfrage beigefügt zu bekommen. Die Umsetzung folgt:

var express = require('express'); 
var app = express.createServer(); 
app.configure('development', function() { 
    app.use(express.cookieParser()); 
    app.use(express.session({secret: 'foo', key: 'express.sid'})); 
}); 

Dann auf jede Anfrage können Sie Sitzung wie folgt zugreifen:

app.get('/your/path', function(req, res) { 
    console.log(req.session); 
}); 

Ich nehme an, Sie eine Art eindeutige Kennung für jede Sitzung zu wollen, so dass Sie verfolgen können sein Kontext. SessionID kann im Cookie 'express.sid' gefunden werden, den wir für jede Sitzung einstellen.

app.get('/your/path', function(req, res) { 
    console.log(req.cookies['express.sid']); 
}); 

Also im Grunde, Sie müssen nichts anderes tun, als Cookie-Parser und ermöglichen Sitzungen für Ihre ausdrückliche App und fügen Sie dann, wenn Sie die Anfrage an diese Funktionen übergeben, können Sie die Session-ID erkennen. Sie MÜSSEN die Anforderung zwar bestehen, Sie können jedoch kein System erstellen, auf dem die Sitzung bekannt ist, da Sie einen Server schreiben und die Sitzung auf Anfrage verfügbar ist.

+2

Nun, Sie verwenden Req als Träger für die Weitergabe von Ausführungskontextdaten. Das ist nicht das was ich suche. Auf einer allgemeineren Ebene suche ich, Argumente in Funktionen ganz zu ersetzen und konstante Namen über Dateien zu haben, die, wenn sie verwendet werden, auf das richtige Objekt zeigen. Also, wenn ich req.irgendwo irgendwo über Dateien, wäre es korrekt req Objekt, wie es automatisch weitergegeben hätte – Raks

+0

Nun, anstatt das ganze System dafür zu schreiben, sollten Sie https://github.com/dwbutler/express verwenden -on-railway – instinctious

+2

@Raks hier ist das Problem, dass Sie das Konzept von pro-Datei oder global mit pro-Anfrage verwirren. In Knoten und im ereignisbasierten Netzwerk im Allgemeinen ist die Anforderung der Kontext. Andernfalls gibt es keine Möglichkeit zu unterscheiden, auf welche Sitzung (ein künstliches Konstrukt) Sie verweisen, und Sie erhalten Rassen. Knoten ist weder PHP noch Rails, der gesamte Interpreter bleibt zwischen den Anforderungen bestehen, ebenso wie der globale Bereich. –

0

Ausdrücken, und die allgemeine Praxis für die Erstellung eines HTTP-Stacks auf node.js ist die Verwendung von http Middleware, um die Request- und Response-Objekte, die von Ihrem Server in den Callback kommen, zu verbessern. Es ist sehr einfach und geradlinig.

module.exports = function(req, res, next) { 
    req.session = require('my-session-lib'); 
    next(); 
}; 

req und res werden automatisch in Ihrem Handler übergeben und von ihr werden Sie brauchen, um sie an die entsprechenden Schichten der Architektur zur Verfügung zu halten. In Ihrem Beispiel ist es wie so zur Verfügung:

AppModule2.js

exports.func2 = function(req,res){ 

    // I want to know where the session context in which this code is running 
    req.session; // <== right here 

} 
+3

Sie werden feststellen, dass Sie die Anfrage und Antwort hier eingeben. Das OP bestand darin, das Zeug nicht in jedes Modul zu geben. –

0

Nodetime ist ein Profilierungswerkzeug, das intern nicht, was Sie zu tun versuchen.Es bietet eine Funktion, die Ihren Code so instrumentiert, dass Anrufe, die sich aus einer bestimmten HTTP-Anfrage ergeben, mit dieser Anfrage verknüpft sind. Zum Beispiel, es versteht, wie viel Zeit eine Anfrage in Mongo, Redis oder MySQL verbracht hat. Schau dir das Video auf der Seite an, um zu sehen, was ich meine http://vimeo.com/39524802.

Die Bibliothek fügt Sonden zu verschiedenen Modulen hinzu. Allerdings konnte ich nicht sehen, wie genau der Kontext (URL) zwischen ihnen übergeben wird. Hoffentlich kann das jemand herausfinden und eine Erklärung veröffentlichen.

EDIT: Sorry, ich denke, das war ein Red-Hering. Nodetime verwendet den Stack-Trace, um Anrufe miteinander zu verknüpfen. Bei den Ergebnissen handelt es sich um Aggregate über potenziell viele Aufrufe derselben URL, sodass dies keine Lösung für das Problem von OP ist.

Verwandte Themen