每个 HTTP/会话请求的全局数据? [英] GLOBAL data per HTTP/Session request?

查看:27
本文介绍了每个 HTTP/会话请求的全局数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

有没有办法在每个会话/http 请求中创建一个变量存储?该变量必须是全局可访问的,并且每个 HTTP 请求/连接/会话都不同,并且不需要在函数之间传递.

例如(只是为了说明):

setVariableThatCanBeAccessedByThisHTTPRequestOnly('a string data');

任何事情都应该可行,但我更愿意避免将其从一个函数传递到另一个函数.

//我试图摆脱将 req 参数传递给所有自定义函数的做法.//我想以某种方式将它存储在一个变量中,它可以全局访问,但只能在该会话/请求中访问.export.functionName = function( req, res ) {customFunctionThatRequiresReq( req );};

原始问题

我最近一直在玩 node.js,对它的 GLOBAL 范围有点担心.假设我们有一个 server.js 文件:

username = "";//全局范围

然后当建立连接并且服务器收到请求时,它将执行以下操作:

username = selectUsernameWithConditions();//这将返回一个用户名

我的问题是:如果 2 台不同的计算机向服务器发送请求,username 的值会独立不同吗?我的意思是,处理第一个请求时的 username 与处理第二个请求时的 username 是否不同,或者它们只是一个变量并将被覆盖?>

如果它们被覆盖,那么存储数据并使它们仅在该请求和/或会话中全局访问的最佳方法是什么?例如下面的代码:

username = selectUsernameWithConditions();//这将返回一个用户名

将为不同的请求分配不同的username,并且不会相互覆盖.

解决方案

是的,但有一些注意事项.您正在寻找一个名为 continuation-local-storage 的模块.
这允许您为当前请求的剩余回调保留任意数据,并以全局方式访问它.
我写了一篇关于它的博客文章这里.但要点是:

  1. 安装cls:npm install --save continuation-local-storage
  2. 为您的应用创建命名空间(在您应用的主文件顶部)

    var createNamespace = require('continuation-local-storage').createNamespace,namespace = createNamespace('myAppNamespace');

  3. 创建一个在 cls(continuation-local-storage)命名空间中运行下游函数的中间件

    var getNamespace = require('continuation-local-storage').getNamespace,namespace = getNamespace('myAppNamespace'),app.use(function(req, res, next) {//包装来自请求和响应的事件namespace.bindEmitter(req);namespace.bindEmitter(res);//在我们创建的命名空间范围内运行以下中间件命名空间.运行(函数(){namespace.set('foo', '一个字符串数据');下一个();});});

  4. 由于您在 namespace.run 中运行了 next,因此任何下游函数都可以访问命名空间中的数据

    var getNamespace = require('continuation-local-storage').getNamespace,namespace = getNamespace('myAppNamespace');//一些无法访问 req 的下游函数...函数 doSomething() {var myData = namespace.get('foo');//myData 将是一个字符串数据"}

  5. 需要注意的是,某些模块可能会丢失"由 cls 创建的上下文.这意味着当你在命名空间上查找 'foo' 时,它不会有它.有几种方法可以解决这个问题,即使用另一个模块,如 cls-redis,cls-q,或绑定到命名空间.

QUESTION:

Is there any way to create a variable storage in per session/http request? The variable must be globally accessible and different per HTTP request/connection/session, and need not be passed from function to function.

For example (just to illustrate):

setVariableThatCanBeAccessedByThisHTTPRequestOnly( 'a string data' );

Anything should work, but I'd prefer to stay away from passing it from function to function.

//I'm trying to get rid of passing req parameter to all custom functions.
//I'd like to store it in a variable somehow, that it can be accessed globally, but only within that session/request.
exports.functionName = function( req, res ) {

   customFunctionThatRequiresReq( req );

};

ORIGINAL QUESTIONS

I've been playing with node.js lately, and have a little concern about its GLOBAL scope. Let's say we have a server.js file:

username = ""; //Global scope

Then when a connection is established and the server receives a request, it will do the followings:

username = selectUsernameWithConditions(); //This will return a username

My question is: If 2 different computers are sending the requests to the server, will the value of username be independently different? I mean, does the username when the first request is processed different from the username when the second request is processed, or they are just one variable and will be overridden?

If they are overridden, what is the best way to store data and make them globally accessible within that requests and/or session only? For example, the following code:

username = selectUsernameWithConditions(); //This will return a username

Will assign username differently for different requests and not overriding each other.

解决方案

Yes, with some caveats. You're looking for a module called continuation-local-storage.
This allows you to keep arbitrary data for the remainder of callbacks for the current request, and access it in a global fashion.
I wrote a blog post about it here. But the gist is this:

  1. Install cls: npm install --save continuation-local-storage
  2. Create a namespace for your app (at the top of the main file for your app)

    var createNamespace = require('continuation-local-storage').createNamespace, 
        namespace = createNamespace('myAppNamespace');
    

  3. Create a middleware that runs downstream functions in the cls (continuation-local-storage) namespace

    var getNamespace = require('continuation-local-storage').getNamespace,
        namespace = getNamespace('myAppNamespace'),
    
    app.use(function(req, res, next) {    
      // wrap the events from request and response
      namespace.bindEmitter(req);
      namespace.bindEmitter(res);
    
      // run following middleware in the scope of the namespace we created
      namespace.run(function() {
        namespace.set(‘foo’, 'a string data');
        next();
      });
    });
    

  4. Since you ran next within namespace.run, any downstream function can access data in the namespace

    var getNamespace = require('continuation-local-storage').getNamespace,
        namespace = getNamespace('myAppNamespace');
    
    // Some downstream function that doesn't have access to req...
    function doSomething() {
      var myData = namespace.get('foo');
      // myData will be 'a string data'
    }
    

  5. There is the caveat that certain modules can "lose" the context created by cls. This means that when you go to lookup 'foo' on the namespace, it won't have it. There are a few ways to deal with this, namely using another module like cls-redis, cls-q, or binding to the namespace.

这篇关于每个 HTTP/会话请求的全局数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆