分离Node.js服务器和客户端
比方说,我正在写一个服务器和客户端的Web应用程序。
- 服务器起到API的作用,并使用快速框架。
- 客户端只是一个静态javascript / html文件的
node-static
应用程序。
我希望能够分开部署,彼此独立 – 或两者同时部署。
这是我如何设想的目录结构:
/my-app app.js /server server.js /client client.js
我希望能够以三种不同的方式运行它:
-
在一些端口上运行服务器(API)(比如说3000):
my-app/server> node server.js ...Server listening on localhost:3000/api
-
运行客户端(即从/ client目录中提供静态文件):
my-app/client> node client.js ...Server listening on localhost:4000/client
-
在同一个端口上运行服务器和客户端(通过单个node.js实例):
my-app> node app.js ...Server listening on localhost:5000
这在节点中是否可用,以及configuration它的正确方法是什么?
我开始如下:
///////////// // server.js ///////////// // Run the server if this file is run as script if(module.parent){ app.listen("3000/client") } ///////////// // client.js ///////////// var static = require('node-static'); var file = new(static.Server)('.'); var app = require('http').createServer(function (request, response) { request.addListener('end', function () { file.serve(request, response); }); }); if(module.parent){ app.listen("4000/client"); } ///////////// // app.js ///////////// server = require("server/server.js") server.app.listen("5000/api") client = require("client/client.js") client.app.listen("5000/client") <--- ?????
我不知道如何挂接我的app.js中的 客户端和服务器,以便他们都从相同的端口/进程/线程等服务…
注:原谅代码,它没有testing,可能不正确。 我是node.js的新手
任何提示赞赏。
当从同一个脚本启动服务器和客户端时,你可以实例化一个connect
( express
)的服务器实例,并且当URL以public
开始时connect
请求到node-static
,否则connect
。
就像是
var connect = require('connect'); server = connect.createServer(); server.use('/public', client.handler_function); server.use(server.express_handler_function);
应该做。 您需要在client.js
公开function(request, response)
,以便通过client.handler_function
引用它,并为express应用程序执行相同的操作(请参阅文档)。
例如,在client.js
使用函数会涉及到如下内容:
var static = require('node-static'); var file = new(static.Server)('.'); var handler = function (request, response) { request.addListener('end', function () { file.serve(request, response); }); }; var app = require('http').createServer(handler); if(module.parent){ app.listen(4000); console.log("Server (static) listening on 4000") } module.exports = { handler_function: handler };
所以你可以通过执行来handler
:
var client = require('client'); // this returns the object you've set to `module.exports` in `client.js` [...] server.use('/public', client.handler_function);
其他方法
我上面详述的东西似乎是最接近你想要的(根据你最后的编辑澄清)。 但是还有其他的select:
-
保留位于网站根目录的静态和明确生成的url,例如
example.com/a_statically_served_script.js
和example.com/api_endpoint
; 首先尝试提供静态文件,如果找不到,则将请求发送到基于快件的应用程序 -
使用
app.js
脚本在不同端口(或unix域套接字)上启动两个服务器,并在它们前面使用节点代理 (或类似的东西,甚至nginx / apache作为反向代理)
同根
对于第一种方法,你需要添加一个error handling程序file.serve
,如
file.serve(request, response, function(e, res) { if (e && (e.status == 404)) { // if the file wasn't found if (next) { next(request, response); } } }
next
应该是client.js
脚本中的一个variables,当脚本直接运行时,它不会被设置,而是需要脚本的时候(查看文档中节点模块和导出的工作方式) – 设置时, next
指的是一个函数,它需要(req, res)
并提供它们来expression(查看关于如何执行此操作的快速文档)。
备注
请记住,这不是一个详尽的答案:这只是一堆关于什么文件查找和你可以用什么技术来解决问题的指针。
值得记住的事情是,在节点中,请求处理程序通常由function(request, response)
来表示和实现。 这个成语在connect
/ express
被扩展为funciton(request, response, next)
:这里next
代表通过server.use(handler)
function(request, response)
挂载到服务器的处理程序链中的下一个可用处理程序( function(request, response)
的formsfunction(request, response)
server.use(handler)
。
我对OP有类似的要求,但不需要分别执行小节…我只想单独的文件夹,因为我不喜欢在服务器的代码文件夹中嵌套客户端代码。 从技术上讲,避免这样做是不可能的,所以我在文件系统中创build了一个抽象级别来缓解我的困扰。 这是我的项目的根源:
-client -server -node_modules -app.js
client
包含所有public
通常会(所有客户端文件被提供),即至lessindex.html
。
server
可能是也可能不是一个Node模块(在我的情况下,它不一定是)。 这里有你的应用程序特定的服务器代码。 您可以重新require
与您的基础app.js
相同的文件,因为它不会有任何区别,并会工作得很好。
node_modules
显然是Node需要的,最好留在项目的根目录下,因为server
任何require
可以通过项目文件夹层次结构向上search,以便在根目录find这个公共的模块存储库 。
app.js
只包含以下内容:
var path = require('path'); var express = require('express'); app = express(); require('./server/server.js'); app.use(express.directory(path.join(__dirname, '/'))); //optional, directory browsing app.use(express.static(path.join(__dirname, '/'))); app.use(express.errorHandler()); app.listen(process.env.PORT || 5000);
…正如你所看到的,根脚本中只有最less的代码。 所有非常重要的应用程序特定的
请注意,variablesapp
不使用var
声明。 通过避免var
,我们使它成为全局的,并允许它在server.js
被访问,而不需要做任何事情。
所以你会做node app
来运行,如果这还不清楚。
- node.js如何访问参数的成员方法?
- ForBiddenError在Node.js / Express.js / Angular2中
- 如何使用swagger-express-mw上传文件并expression?
- 如何用express-http-proxy修改响应头
- NodeJS / Express:隐式地将自定义中间件的数据推送到渲染调用
- nodeJSvideostream,当用户断开或移动到不同的页面时,连接不会closures
- 用gulp运行一个命令来启动Node.js服务器
- Shopify。 用shopify-node-api更新元字段时出现问题
- 在request.pipe之前防止快速的body-parser移除主体