Шаблон программирования Node.js для получения контекста выполнения - PullRequest
16 голосов
/ 29 марта 2012

Я пишу веб-приложение в node.js.Теперь каждая обработка на сервере всегда происходит в контексте сеанса, который либо извлекается, либо создается на самом первом этапе, когда запрос попадает на сервер.После этого выполнение проходит через несколько модулей и обратных вызовов внутри них.Я борюсь с тем, чтобы создать шаблон программирования так, чтобы в любой точке кода объект сеанса был доступен без того, чтобы программист требовал, чтобы он передавал его в качестве аргумента при каждом вызове функции.

Если всекод был в одном файле, у меня могло бы быть закрытие, но если в других файлах есть вызовы функций для других модулей, как мне запрограммировать так, чтобы объект сеанса был доступен в вызываемой функции без передачи его в качестве аргумента.Я чувствую, что должна быть какая-то связь между двумя функциями в двух файлах, но как это устроить, вот где я застреваю.

В общем, я хотел бы сказать, что всегда есть контекст выполнения, который может бытьсеансовый или сетевой запрос, обработка которого распределяется по нескольким файлам и объект контекста исполнения должен быть доступен во всех точках.На самом деле может быть несколько вариантов использования, например, наличие одного объекта журнала для каждого сетевого запроса или одного объекта журнала на сеанс.А сантехника, необходимая для выполнения этой работы, должна быть установлена ​​сбоку, чтобы прикладной программист не беспокоился об этом.Он просто знает, что контекст выполнения доступен во всех местах.

Я думаю, что это должна быть довольно распространенная проблема, с которой сталкиваются все, поэтому, пожалуйста, дайте мне несколько идей.

Ниже приводится проблема

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

    }

Ответы [ 4 ]

8 голосов
/ 05 августа 2012

Вы можете достичь этого, используя Домены - новая функция узла 0.8.Идея состоит в том, чтобы запускать каждый запрос в своем собственном домене, предоставляя пространство для данных для каждого запроса.Вы можете получить доступ к домену текущего запроса без необходимости передавать его через process.domain.

Вот пример настройки для работы с express: Как использовать Node.js 0.8.x доменов с экспрессом?

Обратите внимание, что домены в целом несколько экспериментальны, и процесс. Домен в частности недокументирован (хотя, очевидно, он не уходит в 0.8 и есть некоторые дискуссии о том, чтобы сделать его постоянным).Я предлагаю следовать их рекомендации и добавить свойство для приложения в process.domain.data.

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

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

0 голосов
/ 30 марта 2012

Что делает Express, и обычной практикой для создания стека http на node.js является использование промежуточного программного обеспечения http для «улучшения» или добавления функциональности к объектам запросов и ответов, поступающих в обратный вызов с вашего сервера. Это очень просто и понятно.

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

req и res автоматически передаются в ваш обработчик, и из них вам нужно будет сделать их доступными для соответствующих уровней вашей архитектуры. В вашем примере это доступно так:

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

}
0 голосов
/ 20 апреля 2012

Nodetime - это инструмент профилирования, который внутренне выполняет то, что вы пытаетесь сделать. Он предоставляет функцию, которая обрабатывает ваш код таким образом, что вызовы, возникающие в результате определенного HTTP-запроса, связаны с этим запросом. Например, он понимает, сколько времени запрос тратится в Mongo, Redis или MySQL. Взгляните на видео на сайте, чтобы понять, что я имею в виду http://vimeo.com/39524802.

Библиотека добавляет зонды в различные модули. Однако я не смог увидеть, как именно контекст (URL) передается между ними. Надеюсь, кто-нибудь сможет это выяснить и опубликовать объяснение.

РЕДАКТИРОВАТЬ: Извините, я думаю, это была красная сельдь. Nodetime использует трассировку стека для связи вызовов друг с другом. Результаты, представленные в нем, представляют собой совокупность потенциально многих вызовов одного и того же URL-адреса, поэтому это не решение проблемы OP.

0 голосов
/ 29 марта 2012

Поскольку вы используете Express, вы можете привязать сеанс к каждому запросу.Реализация следующая:

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

Затем при каждом запросе вы можете получить доступ к сеансу следующим образом:

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

Я предполагаю, что вы хотите иметь какой-то уникальный идентификатор для каждого сеанса, поэтомучто вы можете проследить его контекст.SessionID можно найти в файле cookie «express.sid», который мы устанавливаем для каждой сессии.

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

Таким образом, в принципе вам не нужно ничего делать, кроме как добавить анализатор файлов cookie и включить сеансы для своего экспресс-приложения, а затем, когда вы передаете запрос этим функциям, вы можете распознать идентификатор сеанса.Вы ДОЛЖНЫ передать запрос, однако вы не можете создать систему, в которой он просто знает сеанс, потому что вы пишете сервер, а сеанс доступен по запросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...