【socket.io】複数サーバーへの対応メモ

はじめに

今更な内容ですが実際に試したことがなかったのでメモ。
socket.ioをスケールアウトさせるような規模のサービスを作る機会がないのでやっていなかった。。。
まぁ今後もあるかどうか不明だけど、いちおう試しということで

実装自体はredisのpub/subを使ってくれるみたいで簡単だった

> サーバー構成
web / web2 / redisという3台構成を想定
ipは順番に192.168.33.10 / 20 / 30とする

Redisサーバ構築

redisインストール
※バージョンは今時点の最新(たぶん)

root> cd /usr/local/src/
root> wget http://download.redis.io/releases/redis-3.2.3.tar.gz
root> tar xvfz redis-3.2.3.tar.gz
root> cd redis-3.2.3
root> make && make install

設定ファイル編集
とりあえずWebサーバーからは接続できるようにはしておく
(テストなのでここでは全許可にしている)

root> cp src/redis.conf /etc/redis.conf

/etc/redis.conf

#bind 127.0.0.1
bind 0.0.0.0 # Webサーバーから接続できるように

・・・

#daemonize no
daemonize yes

#logfile ""
logfile "/var/log/redis.log"

起動

redis-server /etc/redis.conf

Webサーバ構築

webとweb2で行う

node.jsインストール

http://qiita.com/akippiko/items/3708016fc43da088021c
こちらの内容をそっくりそのままでok

reidsインストール

redisサーバに接続したいのでこちらにもいれておく
手順はredisサーバーにいれたので同じ(redis.confはいじってない)

接続確認

redis-cli -h 192.168.33.30 -p 6379

サーバー側実装

socket.ioインストール

npm install socket.io sockt.io-redis

server.js

var io = require("socket.io").listen(3000);
var redis = require("socket.io-redis");

io.adapter(redis({
    host: "192.168.33.30",
    port: 6379
}));

io.sockets.on("connection", function(socket) {
    socket.on("client2server", function(data) {
        socket.broadcast.emit("server2client", data);
    });
});

起動

node server.js

クライアント側実装

index.html

<input type="text" id="text" />
<input type="button" value="send" onclick="send();"/>
<div id="messages"></div>

<script src="./node_modules/socket.io-client/socket.io.js"></script>
<script>
var web = "192.168.33.10";
var socket = io.connect("http://" + web + ":3000/");
function send() {
  var value = document.getElementById("text").value;
  socket.emit("client2server", {
    "value": value
  });
}
socket.on("server2client", function(data) {
  var messages = document.getElementById("messages");
  var text = document.createTextNode(data.value);
  messages.appendChild(text);
});
</script>

index2.html

// index.htmlと同じでWebサーバーのipだけ異なる

・・・

var web = "192.168.33.20";

・・・

ここまでで実装完了。あとは確認
ブラウザを2つ立ち上げてindex.htmlとindex2.htmlからメッセージを送信するとリアルタイムに反映されることが確認できた

簡単にできたけど実際にスケールアウトが必要な規模だと色々チューニングしなくてはならないのだろうな・・・以上です