Node.js勉強会

山中夏樹
概要
• Node.jsとはどういうものか
• リアルタイム通信について
• Socket.IOについて
Node.jsとは?
• サーバーサイドJavascript。PHPやPerlなどと同
じようなことができる
• RedisやNginxのようにイベント駆動の仕組み
で動きシングルスレッド・シングルプロセス
• コネクション毎にプロセスが作られるapache
等における大量アクセスの問題点克服の為
作られた
• ノンブロッキングIOによる非同期処理を実現
している
シングルスレッド・シングルプロセスとは
apacheの場合
コネクション毎にプロセスが貼られる
サーバー

クライアント

httpdプロセス

クライアント

httpdプロセス

クライアント

httpdプロセス
シングルスレッド・シングルプロセスとは
Node.jsの場合
常に同じプロセス内
サーバー

クライアント

クライアント

クライアント

nodeプロセス
ノンブロッキングIOとは
コンピュータ内部のCPUと周辺装置のデー
タ入出力(I/O)において、データの送受信
の完了を待たずに他の処理を開始する方
式。並列処理の一種。

JavaScriptの非同期処理の仕組みを利用
(コールバック地獄)
ノンブロッキングIOとは

例えばこんな時にこう書く
• お題
下記の処理を実装せよ
1.
2.
3.
4.
5.

「0」を出力する
1秒待つ
「1」を出力する
1秒待つ
「2」を出力する
ノンブロッキングIOとは

シェルスクリプトの場合(同期)
#!/bin/sh
echo 0
sleep 1
echo 1
sleep 1
echo 2
上から順番に処理される。
とても非常に素直な書き方。
ノンブロッキングIOとは

JavaScriptの場合(非同期)
console.log(0);
setTimeout(function(){
console.log(1);
setTimeout(function(){
console.log(2);
}, 1000);},
1000);
setTimeoutの引数になっているfunctionをコールバックといいます。
引数に関数を渡すので渡された関数の処理が終わった後に呼ばれる
→下手すると5重6重のネストが生まれる
→コールバック地獄
■メリット
• リアルタイム通信が割と簡単に実装できる
• 軽くて速い!
• javascriptなのでUIの人もとっつきやすい
■デメリット
• よくメモリリークが問題になる

• シングルプロセス・シングルスレッドなのでマ
ルチコアを活かすには工夫が必要
• プログラムの反映に再起動が必要(課金系に
向かない)
対応プラットフォーム

• Windows
• Mac
• Linux
それぞれでインストーラーが用意されており、公式サ
イトからそれを落としてインストールするだけ。

• 拡張性
npmというパッケージ管理ツールによりサードパーティ
製のモジュールを追加することができる。PHPのPEAR
やPerlのCPANみたいな。
モジュール一覧
■npmモジュール
•
socket.io - リアルタイムWEBアプリケーションによく使われ
る
•
node-mysql - MySQLのDBに接続
•
node-redis - Redisに接続
•
node-gcm - Androidのプッシュを送信
•
node-apn - iPhoneのプッシュを送信
•
ursa - 秘密鍵暗号・複合化
■公式モジュール
•
crypto - 共通鍵暗号・複合化
•
fs - ファイルを操作
•
http - apacheのようなHTTPサーバーを立てたり、HTTPリク
エストを飛ばしたりできる(公式)
•
ReadableStream,Writable Stream (JAVAみたいな?)
リアルタイム通信について
• node.jsはリアルタイム通信を作りたい!など
の時によく使われるらしい。
• しかし、”リアルタイム通信”なWEBアプリケー
ションはnode.jsでなくとも構築できます。
• そこで、どうやってリアルタイム通信を構築し
ているか理解する為にサーバーからのプッ
シュ送信によく使われる仕組みをいくつか説
明しておきます。
XmlHttpRequest(XHR)について
• ウェブブラウザ上のJavascriptから発行される
HTTPリクエストを発信するオブジェクトの名前。
• Ajax通信の基本Object

• それを利用し、サーバーから情報を送りたい
時までレスポンスを返さず接続を張りっぱな
しにすることを”ロングポーリング”という。
socket.ioでも一部取り入れられている。
WebSocketについて
• HTTPを拡張した通信規格の一つ。
• Webサーバーとウェブブラウザの双方向通信
用に作られた。これができるまでは
XmlHttpRequestをもとに作られた擬似的双方
向通信しかなかった。
• 一度コネクションをはるとその上でデータの
送受信を行う為、通信量がXHRより少ない。
• 対応ブラウザが少ない
WebSocketとXHR
XHR

WebSocket

引用:http://labs.opentone.co.jp/?p=2522
Socket.IOについて
• トライフォート社で使用されているリアルタイ
ム通信技術。
• もともとは氾濫しているブラウザ仕様の差異
を吸収し、クロスブラウザで使える双方向通
信システムを構築する為に作られた。

• その為、独自プロトコルみたいになっている
Socket.IO通信フロー
クライアント

サーバー

クライアント

接続

Handshake
(WebSocketか
XHRポーリングか判別)

双
方
向
通
信
が
確
立

接続

Handshake
(WebSocketか
XHRポーリングか判別)

チャット送信

チャット受信

チャット送信
チャット受信

双
方
向
通
信
が
確
立
Socket.IOの機能
"Room"という概念
チャットルームのように、あるネームスペースにクライアントをジョインさせると、そ
こに入っているユーザーだけに対してプッシュ送信ができる。
ただのWebSocketライブラリ等にはない機能で、実装が楽。
コード例

部屋に入る
socket.join("ルーム1");
部屋から出る
socket.leave("ルーム1");
部屋全体に向けてデータ送信
io.sockets.to("ルーム1").emit(data);

ネームスペース“ルーム1”にjoin

ネームスペース“ルーム1”からleave

ネームスペース“ルーム1”にemit

ネームスペース=チャットルーム的な区分け
複数サーバーでSocket.IO
RedisPubSubによるサーバー間セッション共有
Socket.IOの機能として組み込まれている。Redisのhost,portを指定するだけ
Redis

ネームスペースやクライア
ントのセッションIDを共有

サーバー1

サーバー2

Socket.ioプロセス

Socket.ioプロセス

バランサーサーバー

クライアント

クライアント

クライアント

クライアントはどのサーバーへつなぐか意識しなくてよい

クライアント
リアルタイム通信ができる仕組み
実はnode.js以外にもいろいろあるんです。

• Jetty - Webサーバ。JAVA。WebSocketをサポート
• Play - JAVAやScalaで書けるWebフレームワーク。
WebSocketをサポート
• GoogleのMobile Backend Starter - サーバーを介さ
ずAndroid同士のチャットができる。
参考:やんざむさんのブログ
リアルタイム通信ができる仕組み
WebSocket以外にもこんなものが。

• Comet - Ajax通信で、WEBサーバーがデータを更新
するまでレスポンスを返さないとか。

• SPDY - HTTP通信を拡張したプロトコル。TLS接続の
上にセッション層を追加。LINEのバックグラウンド

• SIP - Session Initiation Protocol。UDPにも対応したプ
ロトコル。動画などもリアルタイムにやりとりできる
以上

Nodeについて