首页 \ 问答 \ Node.js + Nginx - 现在呢?(Node.js + Nginx - What now?)

Node.js + Nginx - 现在呢?(Node.js + Nginx - What now?)

我在我的服务器上设置了Node.js和Nginx。 现在我想使用它,但在我开始之前有两个问题:

  1. 他们应该如何合作? 我应该如何处理请求?
  2. Node.js服务器有两个概念,哪一个更好:

    一个。 为需要的每个网站创建一个单独的HTTP服务器。 然后加载程序开始时的所有JavaScript代码,因此代码将被解释一次。

    湾 创建一个单独的Node.js服务器来处理所有Node.js请求。 这将读取所请求的文件并省略其内容。 因此,每个请求都会解释文件,但服务器逻辑要简单得多。

我不清楚如何正确使用Node.js。


I've set up Node.js and Nginx on my server. Now I want to use it, but, before I start there are 2 questions:

  1. How should they work together? How should I handle the requests?
  2. There are 2 concepts for a Node.js server, which one is better:

    a. Create a separate HTTP server for each website that needs it. Then load all JavaScript code at the start of the program, so the code is interpreted once.

    b. Create one single Node.js server which handles all Node.js requests. This reads the requested files and evals their contents. So the files are interpreted on each request, but the server logic is much simpler.

It's not clear for me how to use Node.js correctly.


原文:https://stackoverflow.com/questions/5009324
更新时间:2023-09-29 16:09

最满意答案

[过时...

您可以得到的最接近的定义签名为:

module type SOURCE = sig
  type 'a ctx = 'a constraint 'a = #CouchDB.ctx
  type source
  val get : source -> 'a ctx -> string 
end

但是,当然,你也可以写下:

module type SOURCE = sig
  type source
  val get : source -> #CouchDB.ctx -> string 
end

编辑:请注意,OCaml使用结构打字的对象。 这意味着,即使你想要,你也不能比上述更具限制性。 它甚至没有限制参数成为CouchDB.ctx或派生类的实例 - 任何具有(至少)相同方法的对象都是兼容的。 即使你写作

  val get : source -> CouchDB.ctx -> string 

你可以传递任何具有相同方法的对象。 类型CouchDB.ctx只是一个特定结构对象类型的缩写,恰好与相同名称的类生成的对象相匹配。 它不限于那些。 可以肯定的是:这被认为是一项功能。

======]

编辑2:通过扩展示例,我现在可以看到你想要什么以及为什么。 不幸的是,这在OCaml中是不可能的。 你需要部分抽象类型。 也就是说,你需要能够写作

module type SOURCE = sig
  type ctx < CouchDB.ctx
  ...
end

这在OCaml中不可用。 但是,如果您愿意在签名中提供明确的上传,则可以关闭:

module type SOURCE = sig
  type ctx
  val up : ctx -> CouchDB.ctx
  type source = string
  val get : source -> ctx -> string monad
end

然后,在Cache ,您必须用ctx#get替换(S.up ctx)#get ,并且对于ctx#put也是如此。

module Cache = functor (S:SOURCE) -> struct
  type ctx = S.ctx
  type source = S.source
  let get source ctx = 
     bind ((S.up ctx)#get source) ...
end

module SomeSource = struct
  type ctx = AsyncDB.ctx
  let up ctx = (ctx : ctx :> CouchDB.ctx)
  type source = string
  let get s ctx = ...
end

module SomeCache = Cache (SomeSource)

请注意,我还在签名SOURCE type source = string 。 没有这一点,我看不出ctx#get source可能会如何在Cache函数中进行类型检查。


[Obsolete...

The closest you can get is defining the signature as:

module type SOURCE = sig
  type 'a ctx = 'a constraint 'a = #CouchDB.ctx
  type source
  val get : source -> 'a ctx -> string 
end

But of course, you could as well just write:

module type SOURCE = sig
  type source
  val get : source -> #CouchDB.ctx -> string 
end

Edit: Note that OCaml uses structural typing for objects. That means that even if you wanted, you cannot get any more restrictive than the above. It does not even limit arguments to get to be instances of CouchDB.ctx or a derived class -- any object that has (at least) the same methods will be compatible. Even when you write

  val get : source -> CouchDB.ctx -> string 

you can pass any object that has the same methods. The type CouchDB.ctx is just an abbreviation for a specific structural object type that happens to match the objects generated by the class of the same name. It is not restricted to those. And just to be sure: that is considered a feature.

======]

Edit 2: With the extended example, I now see what you want and why. Unfortunately, that isn't possible directly in OCaml. You would need partially abstract types. Namely, you would need to be able to write

module type SOURCE = sig
  type ctx < CouchDB.ctx
  ...
end

This is not available in OCaml. However, you can get close if you are willing to provide an explicit upcast in the signature:

module type SOURCE = sig
  type ctx
  val up : ctx -> CouchDB.ctx
  type source = string
  val get : source -> ctx -> string monad
end

Then, in Cache, you have to replace occurrences of ctx#get with (S.up ctx)#get, and likewise for ctx#put.

module Cache = functor (S:SOURCE) -> struct
  type ctx = S.ctx
  type source = S.source
  let get source ctx = 
     bind ((S.up ctx)#get source) ...
end

module SomeSource = struct
  type ctx = AsyncDB.ctx
  let up ctx = (ctx : ctx :> CouchDB.ctx)
  type source = string
  let get s ctx = ...
end

module SomeCache = Cache (SomeSource)

Note that I also made type source = string transparent in the signature SOURCE. Without that, I cannot see how ctx#get source can possibly type-check in the Cache functor.

相关问答

更多
  • 类型约束中使用的任何类型变量的范围是包含let-expression的主体。 如果表达式是相互递归的,那么范围将扩展到整个相互递归表达式集。 范围不能减少。 Let-expression是一个输入原语。 无法隐藏或覆盖类型变量。 每当引入新的类型变量时,都会在当前的类型上下文中查找它。 如果它已经被引入,那么它是统一的。 否则,将向上下文添加新类型变量。 (以后可以用于统一)。 一个澄清这个想法的例子: let rec f g h x y = g (x : 'a) + h (y : 'a) and e (x ...
  • 做这样的事情的正确方法是做到以下几点: 在orders.mli中写道: (* This define the signature *) module type ORDERING = sig type t val isLess : t -> t -> bool end (* This define a module having ORDERING as signature *) module StringOrdering : ORDERING 编译文件: ocamlc -c ordering.m ...
  • [过时... 您可以得到的最接近的定义签名为: module type SOURCE = sig type 'a ctx = 'a constraint 'a = #CouchDB.ctx type source val get : source -> 'a ctx -> string end 但是,当然,你也可以写下: module type SOURCE = sig type source val get : source -> #CouchDB.ctx -> string e ...
  • 一个笨重但可行的解决方案是将您的函数转换为newtype : newtype Binder = Binder (forall w. WidgetClass w => (GObject -> w) -> String -> IO w) widgetBinder :: FilePath -> IO Binder widgetBinder file = do Just ui <- xmlNew file return $ Binder (xmlGetWidget ui) loadDialog file ...
  • 在QPL许可证下使用与OCaml一起分发的compiler-lib -lib 。 它拥有创建自己的编译器所需的一切(甚至还有一些文档 )。 compiler-lib本质上是一个作为库提供的编译器。 否则,您可以使用camlp4来获取分析树,但是您需要从头开始重新实现其他所有功能。 但在这种情况下,您不会受限于QPL。 Use compiler-lib that is distributed with OCaml under QPL license. It has everything needed to c ...
  • 以下编译就好了: type A<'a>(x) = member __.Get : 'a = x abstract PairWith : 'b -> ('a * 'b * int) default __.PairWith y = x, y, 1 type B<'a>(x) = inherit A<'a>(x) override __.PairWith y = x, y, 2 let pairAB (x : #A<'a>) y = x, x.PairWith ...
  • 我个人用if(is(typeof(T.init != E.init) == bool))确保它是关于类型的变量 (然后当你希望T成为一个范围时( if(isInputRange(T) && is(typeof(T.init.front != E.init) == bool)) ,则丢失数组表示法if(isInputRange(T) && is(typeof(T.init.front != E.init) == bool)) ) 编辑:测试这样的事情的最好方法是扩展测试用例: 如果我们采取不同的功能: int ...
  • 我在这做错了什么? 我猜测类型变量a不受mkGraph类型签名的约束,但是mkGraph的定义是否应该强制节点和边缘的签名中的a是相同的? 你猜对了; 另一个是新型变量。 这意味着,它不仅与mkGraph的签名不同,而且是一个全新的通用量化类型变量,这是不正确的。 因此,内部签名中称为a的类型既不是多态的,也不是单一已知的类型。 不,根据Haskell标准,它“不应该”。 在Haskell 98中,实际上不可能为代码中的nodes和edges编写类型签名。 是的,那有点傻。 但是,GHC提供了一个Scope ...
  • 将类约束视为推断的函数参数是有用的,因为它们对GHC Core中的函数和函数应用程序感到厌恶。 让我们去问一下这个类型: newtype ShowDict a = ShowDict (a -> String) test1 :: forall x. (ShowDict x -> x) -> String 或者更简单: test1 :: forall x. ((x -> String) -> x) -> String 这种类型并不真正有用。 通过参数化,它的实现必须是返回一些字符串的常量函数。 使用原始的非 ...
  • 答案1:不。您想要的是超出OCaml类型系统的范围。 答案2:您可以将zerotree定义为与tree完全不同的类型。 type zerotree = | ZLeaf | ZNodeL of int * zerotree * tree | ZNodeR of ... (* left for the reader *) | ZNodeI of ... zerotree是ZLeaf ,叶子为0 ; ZNodeL ,一个左子树ZNodeL树的节点; ZNodeR ,一个右子树ZNodeR树的节 ...

相关文章

更多

最新问答

更多
  • 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
  • linux的常用命令干什么用的
  • 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
  • 如何交换返回集中的行?(How to swap rows in a return set?)
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
  • Java中的不可变类(Immutable class in Java)
  • WordPress发布查询(WordPress post query)
  • 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
  • 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
  • GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
  • 绑定属性设置器未被调用(Bound Property Setter not getting Called)
  • linux ubuntu14.04版没有那个文件或目录
  • 如何使用JSF EL表达式在param中迭代变量(How to iterate over variable in param using JSF EL expression)
  • 是否有可能在WPF中的一个单独的进程中隔离一些控件?(Is it possible to isolate some controls in a separate process in WPF?)
  • 使用Python 2.7的MSI安装的默认安装目录是什么?(What is the default installation directory with an MSI install of Python 2.7?)
  • 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
  • ckeditor config.protectedSource不适用于editor.insertHtml上的html元素属性(ckeditor config.protectedSource dont work for html element attributes on editor.insertHtml)
  • linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
  • Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
  • 将CouchDB与AJAX一起使用是否安全?(Is it safe to use CouchDB with AJAX?)
  • 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
  • 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
  • Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
  • 无法在新线程中从FREContext调用getActivity()?(Can't call getActivity() from FREContext in a new thread?)
  • 在Alpine上升级到postgres96(/ usr / bin / pg_dump:没有这样的文件或目录)(Upgrade to postgres96 on Alpine (/usr/bin/pg_dump: No such file or directory))
  • 如何按部门显示报告(How to display a report by Department wise)
  • Facebook墙贴在需要访问令牌密钥后无法正常工作(Facebook wall post not working after access token key required)
  • Javascript - 如何在不擦除输入的情况下更改标签的innerText(Javascript - how to change innerText of label while not wiping out the input)
  • WooCommerce / WordPress - 不显示具有特定标题的产品(WooCommerce/WordPress - Products with specific titles are not displayed)