Mais conteúdo relacionado
Semelhante a 自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた (20)
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
- 10. What is node.js?
Javasctiptでサーバーサイドプログラミングを行うことが出来る環境の総称です。
特徴
・V8 javascript(google chromeのjavascript実行環境)を利用しているため、動作が軽快
・イベントドリブンなプログラミングスタイル
・シングルスレッドのイベントループモデル
(apacheのようにリクエスト毎にスレッドを立てるのではなく、シングルスレッドで処理をキュー
にためて実行する。このため、メモリの使用量がapacheなどのサーバーに比べて少ない)
・ノンブロッキングI/O
(i/oの完了を待たずに次の処理が実行される。ブラウザで動作するjavascriptのように、パラレル
で処理が実行される。
普通のイベントループモデルだと重い処理がブロッキングを行って次の処理が遅延するが、
ノンブロッキングI/Oのおかげでnode.jsではブロッキングが発生しない。)
・以上のことから、大量アクセスのあるリアルタイムWEBを始めとしたネットワークプログラミ
ングが得意
- 12. node.jsでWEBアプリケーションとなると....
cofeescript、jadeのほか、Redis、
MongoDBをすぐに扱えるnode.js
史上最強MVCフレームワーク
http://towerjs.org/
rubyのsinatraライクな軽量フレーム
ワーク
http://expressjs.com/
- 15. Architecter
nginx(静的ファイル)
port 80
クライアント
request
response
proxy
簡単な仕様 node.js(動的処理)
・RonRライクなMVCパターンを採用 port3000
・ORMなし
・scafoldなし response
・ Templateエンジンにejsを採用
・jsUnitを採用(予定)
- 18. ディレクトリ構成
miketokyo
|-app
|-config
|-config.js
|-router.js
|-bootstrap.js
|-controllers
|-models
|views
|-layouts
|-system
|-server
|-view.js
|-router.js
|-controller.js
|-share.js
|-response.js
|-utility.js
|-server.js
|-package.json
|-.gitignore
- 19. リクエストハンドラの実装
server.js(紙面の都合上章や略しております。)
var
http
=
require("http");
var
url
=
require("url");
(function
start()
{
function
onRequest(request,
response)
{
//アプリケーション初期化
var
router
=
require("./app/config/router.js");
var
pathname
=
url.parse(request.url).pathname;
var
bootstrap
=
require("./app/config/bootstrap");
bootstrap.init(request,
response);
var
env
=
require("./app/config/env/"
+
bootstrap.env);
var
config
=
require("./app/config/config");
var
share
=
require("./system/server/share");
share.config
=
config;
var
__CONTROLLER__
=
router.controller;
var
__ACTION__
=
router.action;
if(pathname
!=
"/"){
__CONTROLLER__
=
pathname.split("/")[1];
__ACTION__
=
(typeof
pathname.split("/")[2]
==
"string")
?
pathname.split("/")[2]
:
"index";
}
var
className
=
__CONTROLLER__.charAt(0)
+
__CONTROLLER__.substring(1)
+
"Controller";
//クラス名を動的に形成する
var
_controller
=
require("./app/controllers/"
+
className);
var
controllerInstance
=
new
_controller();
controllerInstance.request
=
request;
controllerInstance.response
=
response;
controllerInstance.headers
=
request.headers;
controllerInstance.headers.userAgent
=
require('user-‐agent').parse(request.headers['user-‐agent']).full;
controllerInstance.init();
var
assignVars
=
eval("controllerInstance."
+
__ACTION__
+
"Action()");
var
view
=
require("./system/server/view");
view.render(controllerInstance.layoutPath
,
controllerInstance.renderPath
,
assignVars,
response);
}
http.createServer(onRequest).listen(3000);
})();
- 20. 環境判別等を行うbootstrapを作成する
app/config/bootstrap.js
var
bootstrap
=
{
env
:
"localhost"
,init
:
function(req,
res){
//ホストから環境を判別する
var
this.env
=
(function(host){
var
hostSplits
=
host.split(".");
if(hostSplits[0].match(/dev|stg/)){
return
hostSplits[0];
}else{
return
"production";
})(req.headers.host);
}
}
}
module.exports
=
bootstrap;
- 22. BaseとなるControllerクラスの作成
system/controller.js
function
controller(){}
controller.prototype
=
{
request
:
null,
response
:
null,
headers
:
null,
renderPath
:
null,
layoutPath
:
"base",
init
:
function(){},
//void
redirect
redirect
:
function(url){
this.response.writeHead(302,
{
'Location':
url
});
this.response.end();
},
//void
render
render
:
function(path){
this.renderPath
=
path;
},
//void
layout
layout
:
function(path){
this.layoutPath
=
path;
}
}
module.exports
=
controller;
- 23. Viewクラスの作成
system/view.js
var
fs
=
require("fs");
var
ejs
=
require("ejs");
var
share
=
require("./share");
var
view
=
{
templateVars
:
{}
,viewExt
:
".ejs"
,layoutPath
:
null
,templatePath
:
null
//htmlをクライアントに返す
render
:
function(layoutPath,
templatePath,
templateVars,
response){
var
templatePath
=
share.APP_PATH
+
"views/layout/"
+
templatePath
+
this.viewExt;
fs.readFile(templatePath,"utf8",
function(err,data){
//renderで指定されたtemplateをhtmlに置換して取得する
var
actionData
=
ejs.render(data,vars);
fs.readFile((function(path){
var
templatePath
=
share.APP_PATH
+
"views/";
if(path
!==
undefined
&&
path
!==
null){
return
templatePath
+=
path
+
this.viewExt;
}else{
return
templatePath
+=
share.__ACTION__
+
this.viewExt;
}
})(layoutPath),"utf8",
function(err,data2){
//layoutで指定されたtemplateに、actionDataを埋め込みHTMLとしてクライアントに返す
var
finalOutput
=
ejs.render(data2,{content
:
actionData,
applicationName
:
share.config.applicationName});
response.writeHead(200,
{
'Content-‐Type':
'text/html;
charset=utf-‐8'
});
response.end(finalOutput);
});
});
},
}
module.exports
=
view;
- 24. routerクラスの作成
system/server/router.js
var
url
=
require("url");
var
router
=
{
req:null
,controller:
"app"
,action
:
"index"
,connect
:
function(pattern,
routeUrl){
var
patt
=
pattern.replace('/',
"/");
var
pathname
=
url.parse(this.req.url).pathname;
if(pathname.match(patt)){
this.controller
=
routeUrl.split("/")[0];
this.action
=
routeUrl.split("/")[1];
}
}
}
module.exports
=
router;
- 26. appControllerの作成
app/controllers/appController.js
//ライブラリインポート
var
share
=
require("../../system/server/share");
var
utility
=
require("../../system/server/utility");
function
appController(){}
//継承
var
appController
=
utility.extend(appController,
require("../../system/
server/controller"));
appController.prototype.init
=
function(){
this.layout("base");
}
appController.prototype.indexAction
=
function(){
return
{applicationName:"MikeTokyo"
};
}
appController.prototype.testAction
=
function(){
this.render("test");
}
module.exports
=
appController;
- 27. 各種viewの作成
app/views/layout/base.ejs
<!doctype
html>
<html>
<head>
<meta
charset="UTF-‐8">
<title><%=applicationName
%></title>
</head>
<body>
<%-‐content
%>
</body>
</html>
app/views/index.ejs
<h1><%=applicationName
%>:Index</h1>
<img
src="/img/common/logo.jpg">
<a
href="/app/test"
>testへ</a>
- 29. nginxの設定
/etc/nginxd/nginx.conf
server {
listen 80;
server_name miketokyo.com;
root /var/www/nginx-default;
access_log /var/log/nginx/localhost.access.log;
#指定した拡張子のファイルはnginxでさばく
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
root /var/www/miketokyo/app/webroot/
expires 15d;
}
#プロキシの設定
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}