2012-03-29 12 views
15

Piszę aplikację internetową w pliku node.js. Teraz każde przetwarzanie na serwerze jest zawsze w kontekście sesji, która jest albo pobierana, albo tworzona na pierwszym etapie, kiedy żądanie trafia na serwer. Po tym wykonaniu wykonanie przepływa przez wiele modułów i wywołań zwrotnych w nich. Z czym walczę, to tworzenie wzorca programistycznego, aby w dowolnym momencie kodu obiekt sesyjny był dostępny bez programisty, który wymagałby przekazania go jako argumentu w każdym wywołaniu funkcji.Wzorzec programowania Node.js do uzyskania konturu wykonania

Jeśli cały kod był w jednym pliku, mógłbym mieć zamknięcie, ale jeśli istnieją wywołania funkcji do innych modułów w innych plikach, to jak mam programować, aby obiekt sesji był dostępny w wywołanej funkcji bez przekazywania go jako argument. Czuję, że powinien istnieć jakiś związek między dwiema funkcjami w dwóch plikach, ale jak to zorganizować, to gdzie utknąłem.

Ogólnie chciałbym powiedzieć, że zawsze istnieje kontekst wykonania, który może być sesją lub żądaniem sieci, którego przetwarzanie jest rozłożone na wiele plików, a obiekt kontekstu wykonania ma zostać udostępniony we wszystkich punktach. W rzeczywistości może istnieć wiele przypadków użycia, takich jak posiadanie jednego obiektu dziennika dla każdego żądania sieciowego lub jednego obiektu dziennika na sesję. Instalacje hydrauliczne wymagane do wykonania tej czynności powinny być montowane na boki bez przeszkadzania programistom aplikacji. Po prostu wie, że ten kontekst wykonania jest dostępny we wszystkich miejscach.

Myślę, że powinien on dość powszechny problem napotykany przez wszystkich, więc proszę dać mi kilka pomysłów.

Poniżej 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

Jeśli wymyśliliśmy sposób, aby to zrobić, proszę odpowiedzieć na własne pytanie. –

Odpowiedz

8

Można to osiągnąć za pomocą Domen - nowa funkcja węzła 0.8. Pomysł polega na uruchomieniu każdego żądania w jego własnej domenie, zapewniając miejsce na dane na żądanie. Możesz dostać się do domeny bieżącego żądania bez konieczności przekazywania go za pośrednictwem metody process.domain.

Oto przykład z coraz to konfigurację do pracy z Express: How to use Node.js 0.8.x domains with express?

nocie, że domeny są na ogół nieco eksperymentalny i process.domain w szczególności jest nieudokumentowane (choć podobno nie odchodzi w 0,8 i nie ma dyskusja na temat jej trwałości). Proponuję zastosować się do ich zaleceń i dodać właściwość specyficzną dla aplikacji do process.domain.data.

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

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

0

Ponieważ używasz Express, można uzyskać sesji dołączony do każdego żądania. Realizacja jest następujący:

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

Następnie na każde żądanie, można uzyskać dostęp do sesji tak:

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

Zakładam, że chcesz mieć jakiś unikalny identyfikator dla każdej sesji, dzięki czemu można śledzić jego kontekst. SessionID można znaleźć w pliku cookie "express.sid", który ustawiamy dla każdej sesji.

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

Więc w zasadzie, nie musisz robić nic innego, jak dodać plik cookie parser i włączyć sesje dla wyraźnej aplikacji i wtedy kiedy przechodzą prośbę do tych funkcji, można rozpoznać identyfikator sesji. MUSISZ przekazać żądanie, ale nie możesz zbudować systemu, w którym on po prostu zna sesję, ponieważ piszesz serwer, a sesja jest dostępna na żądanie.

+2

Cóż, używasz polecenia req jako operatora do przesyłania danych kontekstu wykonania razem. Nie tego szukam. Na bardziej ogólnym poziomie, chciałbym zastąpić argumenty w funkcjach łącznie i mającymi stałe nazwy w plikach, które po zastosowaniu wskazują na właściwy obiekt. Więc jeśli zrobię to ponownie w dowolnym miejscu w obrębie plików, będzie to poprawny obiekt, ponieważ automatycznie przekazywałby ten numer – Raks

+0

Zamiast pisać cały system, powinieneś użyć https://github.com/dwbutler/express -na-kolejowa – instinctious

+2

@ Problem polega na tym, że mylisz pojęcie pliku lub globalnego za pomocą żądania. W węźle i ogólnie w sieci opartej na zdarzeniach żądanie jest kontekstem. W przeciwnym razie nie można odróżnić sesji (sztucznej konstrukcji), do której się odwołujesz, i dostajesz wyścigi. Węzeł nie jest ani PHP, ani Railsami, cały interpreter przeżywa między żądaniami, tak jak globalny zasięg. –

0

To co ekspresowe robi, a powszechną praktyką przy budowaniu stosu http na węźle node.js jest użycie oprogramowania pośredniczącego http w celu "ulepszenia" lub dodania funkcjonalności do obiektów żądania i odpowiedzi wchodzących do wywołania zwrotnego z twojego serwera. To bardzo proste i proste.

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

req i rozdzielczości są automatycznie przekazywane do swojego przewodnika, a od ich trzeba zachować je dostępne dla odpowiednich warstw architektury. W przykładzie, jest ona dostępna tak:

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

Zwróć uwagę, że tutaj przekazujesz żądanie i odpowiedź. OP nie musiał przekazywać tych rzeczy do każdego modułu. –

0

Nodetime jest narzędziem, które ma profilowanie wewnętrznie, co próbujesz zrobić.Udostępnia funkcję, która instrumentuje twój kod w taki sposób, że wywołania wynikające z konkretnego żądania HTTP są powiązane z tym żądaniem. Na przykład, rozumie, ile czasu zajęło żądanie w Mongo, Redis lub MySQL. Obejrzyj film wideo na stronie, aby zobaczyć, co mam na myśli: http://vimeo.com/39524802.

Biblioteka dodaje sondy do różnych modułów. Jednak nie byłem w stanie zobaczyć, jak dokładnie kontekst (URL) jest przekazywany między nimi. Mam nadzieję, że ktoś to wymyśli i opublikuje wyjaśnienie.

EDIT: Przepraszam, myślę, że to był czerwony-śledzia. Nodetime używa śledzenia stosu do powiązania wywołań ze sobą. Przedstawione wyniki są zbiorami potencjalnie wielu wywołań tego samego adresu URL, więc nie jest to rozwiązanie problemu OP.