使用したモジュール覚書

使用したモジュール覚書

#pm2
[https://github.com/Unitech/pm2](https://github.com/Unitech/pm2)

P(rocess) M(anager) 2
PM2 is a production process manager for Node.js / io.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.

pm2はnode.jsアプリプロセスの管理パッケージです、ロードバランサー機能もビルドインされています。

* 機能
	> * ロードバランサー機能をビルドイン=クラスタリング（native clusterモジュール利用）
	> * デーモンスクリプト
	> * node.jsアプリを0sリロード
	> Ubuntu/CentOS起動スクリプトも提供（Ubuntuはupdaterc.d、ほかのLinuxはchkconfig）
	> * 不安定プロセスを停止させる（無限ループ回避）
	> * コンソール監視
	> * HTTP API
	> * リモートコントロールとリアルタイムAPIインターフェース
	> [pm2 - node.js プロセス管理パッケージ](http://nodejs.osser.jp/node/node-pm2/")

* 他
	* [プロセス管理系ツールまとめ](http://qiita.com/disc99/items/57490f5eef3e2eb685ba) 



* io.jsとは何か
	* Node.jsの派生プロジェクト
	* nodeに取り込まれるらしい [
		* [io.jsについて知っていること](http://yosuke-furukawa.hatenablog.com/entry/2014/12/25/104300) 
		* [Node.js と io.js の統合は最終局面へ](http://yosuke-furukawa.hatenablog.com/entry/2015/05/13/100832)


* Node.jsでのクラスタリング
	> node.jsの問題点として、シングルプロセスで処理をしていて、あるリクエストの処理が長くかかる場合、ほかのすべてのリクエストをブロックする可能性があります。 httpモジュールで、ウェブサーバを起動したとき、同時に処理できるアクセスは、１つだけなので、処理がつまると、後ろに並んでいるリクエストの待ち行列は、ブロックされた状態になります。それらを解決するためにclusterを用いた例がある。
	> 伝統的なUnixプログラミングのforkモデルと同じと捉えて差し支えない。Unixのfork()と異なるのは、Unixのforkは、forkを呼び出した直後のプログラムが親プロセスと子プロセスで実行されますが、node.jsのclusterの場合は、forkを実行すると、同じプログラムが最初から起動されます。
	> [node.js clusterでHTTPサーバをマルチプロセス化する](http://kaworu.jpn.org/javascript/node.js_cluster%E3%81%A7HTTP%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E5%8C%96%E3%81%99%E3%82%8B)

# express

webアプリケーションフレームワーク

* Web Applications. Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
	* 小さい柔軟なwebアプリケーションフレームワーク。webアプリまたはモバイルアプリに様々な堅牢な機能を提供します。
* APIs. With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy.


> Webアプリを構成する上で必要な機能がそろっており、ルーティングやビューヘルパー、セッション管理の機能もデフォルトで提供しています（※永続的なセッション管理には「Redis」などのデータストアが必要な場合もある）。また、ミドルウエアとしての機能を使用し、Expressの機能を独自に拡張することもできます。

## express middleware
* An Express application is essentially a series of middleware calls.Middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application, commonly denoted by a variable named next. Middleware can:
	* Execute any code.
	* Make changes to the request and the response objects.
	* End the request-response cycle.
	* Call the next middleware in the stack.
	
* リクエストがやってきたときにこれらを順次適用していきなさいというもの。順次定義した順番に実行されるので注意。
	* [Express入門 ](http://dotinstall.com/lessons/basic_expressjs/26506)
	* [Express/ミドルウェア](http://hideyukisaito.github.io/expressjs-doc_ja/guide/#middleware)

* [本家](http://expressjs.com/ja/guide/using-middleware.html)


## body-parser


* expressは通常GET値しか解析できない。POST値やJSONを解析するために使用。
	* https://www.npmjs.com/package/body-parser
	* express3までは付express本体に付属していたが、express4からなくなってthird partyになった。[Express入門をexpress 4.xで学ぶ場合のメモ](http://d.hatena.ne.jp/tomute/20140514/1400075607)
	* 他 
		* [express/connectミドルウェアbodyParserを読む](http://bouzuya.hatenablog.com/entry/2013/11/18/235959)
		* bodyParser.urlencoded(options)
			* Returns middleware that only parses urlencoded bodies. This parser accepts only UTF-8 encoding of the body and supports automatic inflation of gzip and deflate encodings. A new body object containing the parsed data is populated on the request object after the middleware (i.e. req.body). This object will contain key-value pairs, where the value can be a string or array (when extended is false), or any type (when extended is true).

# express-session (node-module)
[https://github.com/expressjs/session](https://github.com/expressjs/session)

* expressでセッション管理
	* デフォルトではメモリにセッション情報格納
* options
	* resave – forces session to be saved even when unmodified. (default: true) 
		* 毎回のリクエスト時にsessionは保存（上書き）される。default: true。
		* false = don't save session if unmodified
	
	* saveUninitialized
		* 保存されていないセッションがあったら保存するようにする
		* false = don't create session until something stored
	* 使用例
		* [NODE.JS EXPRESS 4.X系のセッション管理](http://curtaincall.weblike.jp/		blog/?p=842)
		* [node.JsにおけるCSRF対策](http://dev.classmethod.jp/server-side/node-js_csrf/)
		* [Node.js+Express+MongoDBでSessionを利用する、をちょっと整理して理解を試みた](http://izmiz.hateblo.jp/entry/2014/05/30/230816)


# connect-redis (node module)
[https://github.com/tj/connect-redis](https://github.com/tj/connect-redis)

* connect-redis is a Redis session store backed by node_redis
* 使用例
	* [ExpressのSessionデータをRedisで管理する](http://dim5.net/nodejs/using-express-session-redis.html)
	* [USING REDIS TO STORE SESSION VALUES IN NODE JS APPLICATION](http://blog.arisetyo.com/?p=492)
	
# scoket.io
[http://socket.io/](http://socket.io/)

* Socket.IO enables real-time bidirectional event-based communication.
> 複雑なリアルタイムWeb技術の実装方式を隠蔽し、すべてのブラウザ・モバイルデバイスでリアルタイム通信を可能とすること」を目的に開発されているnode.js用サーバー側ライブラリとブラウザ用JavaScriptライブラリのセットです
> [Socket.ioとは何か?リアルタイムWebアプリケーションを実現する技術をまとめてみた](http://qiita.com/masarufuruya/items/2bd5dfe03096057af63f) 

* 使い方
	* [http://socket.io/get-started/chat/](http://socket.io/get-started/chat/)

```
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});
```

# socket.io-redis

* Adapter to enable broadcasting of events to multiple separate socket.io server nodes. 
* By running socket.io with the socket.io-redis adapter you can run multiple socket.io instances in different processes or servers that can all broadcast and emit events to and from each other.
	* socket.io-redisを用いてsocket.ioを利用することによって、異なるプロセス間、サーバ間でもブロードキャスト、イベントを共有することができる。
* If you need to emit events to socket.io instances from a non-socket.io process, you should use socket.io-emitter.
	
# pm2 + socket.IO

> pm2でクラスタリングしたsocketサーバーに接続すると、xml-pollingになったり、websocketになったりと接続が不安定。原因はSocket.IO は接続確立までに 2 回リクエストを投げるということです。 そしてこの最初の要求と、 WS の接続要求は、「同じインスタンス」にアクセスする必要があります。 二つの接続がバランスされて別々のサーバに行くと、ハンドシェイクがエラーになり、リトライが発生します。 たまたま二回同じサーバにいけば、接続が確立できるので、バランスするサーバが増えるほど成功確率が減 り、確立までの時間が長くなります。

* 解決策としてredisをセッションキーストアとして利用する、ということのよう。redisのPub/Subを利用して、各プロセス間でセッション共有をする。
	* 他の解決策として、socket.io-redisを利用することでも。
	* 参考
		* [Node.js + Socket.IO + pm2でデーモン化とクラスタリング](http://tomowatanabe.hatenablog.com/entry/2014/01/31/124740)
		* [今更だけどSocket.ioについてまとめてみる](http://blog.wnotes.net/blog/article/nodejs-socketio-summary)
		* [socket.io-redis, socket.io-emitter, sticky-session の違いとは?](http://d.hatena.ne.jp/pospome/20150322/1427041393)

# pm2 + socket.io + socket.io-redis
 * scoket.ioのデフォルトはオンメモリなのでプロセス間での共有ができない。pm2でクラスタリングしていると複数プロセスを動かすことになるので、共有できない問題をsocket.io-redisで解決する 。Redisのpub/subを利用して解決しているらしい。
 
 参考になるレポート
 * socket.io + redis（pub/sub）(nodeのモジュールを使わない) + cluster + を使用した例
 	* [Socket.IO, Redisを使用し各ゲーム間でプッシュ通知するシステム](https://www.cyberagent.co.jp/techinfo/techreport/report/id=8858)