

LINEのようなチャットアプリをhtml5ハイブリッドアプリで作成中です(Monacaを使ってます)。

node.jsとsocket.ioとredisを利用する予定です。

Googleなどで「socket.io
チャット」と検索すると、いろんなサイトでチャットとして動作するコードが書かれていますが、それらは全て「入力した内容がリアルタイム通信している相手に直接送信されるもの」となっています。

私がやりたいのは「送信側は入力した内容をredisに保存する→受取側はredisの中に自分のユーザーIDで保存されているデータがあればポップして、ポップしたデータはredisから削除」というものです。  
つまり「送信側と受取側がsocket.ioによってリアルタイム通信されている」のではなく、「受取側がredisとリアルタイム通信されている」というプログラムになると思います。

ここまで書きましたが、今までPHPしかしておらず、node.jsに関して初心者なので質問したい事があります。

  1. このやり方は可能でしょうか？可能なら、参考になるサイトなども紹介して頂きたいです。

  2. これより一般的なやり方はあるのでしょうか？


CC BY-SA 3.0
2015-11-15T14:45:10.327
18853
2018-12-15T13:02:30.853
2015-11-15T15:17:29.213
11032
11032
question
node.js socket.io redis
Socket.ioを利用したチャットアプリについて


この辺りは自分も何となく知っている程度なのですが、質問内容で実現したいのはいわゆる「Pub/Subメッセージングモデル」というやつなのかなと思いました。  
参考:
[Pub/Subメッセージングモデル](http://itdoc.hitachi.co.jp/manuals/link/cosmi_v0870/APKC/EU070377.HTM)

試しに「socket.io pubsub」で検索してみた結果をいくつか貼っておきます。  
[今更だけどSocket.ioについてまとめてみる](http://blog.wnotes.net/blog/article/nodejs-
socketio-summary)  
[Socket.io + Redis
PubSubでリアルタイムメッセージ配信](http://uorat.hatenablog.com/entry/2015/08/30/190613)  
[socket.io-redis（GitHub）](https://github.com/socketio/socket.io-redis)

ちなみにRedisには標準で「pub/sub」機能があるみたいです。  
[3分でRedisのpub/subを使ってみる](http://otiai10.hatenablog.com/entry/2014/05/04/112426)


CC BY-SA 3.0
2015-11-16T01:36:34.593
18864
2015-11-16T01:36:34.593
3516
18853
answer


MonacaとSocket.ioを使った事がないので可能であるかはわかりませんが、実装方法を自分なりに考えました。もし参考になればと思います。

まず、クライアント1が未接続時に他のクライアント2からメッセージがあった場合は、redisの未読スタックorキューにメッセージを保存します。  
そして次回クライアント2がSocketに接続したときにredisに未読メッセージがあればそれをクライアント2に送信し削除します。Socketとの接続確立以前にメッセージを確認したければ、クライアント2側からサーバーに未読確認のリクエストを送り、restで未読メッセージを受信します。  
もしクライアント1,2がオンラインであればredisには保存せずにメッセージをブロードキャストします。


CC BY-SA 3.0
2015-11-16T02:01:43.550
18867
2015-11-16T02:01:43.550
7232
18853
answer


### 参考になりそうなフレームワーク

既存のWebアプリケーション、フレームワーク、サービスなどが何を使っているかが参考になります。  
特にフレームワークは使っている人が多いので、その構成でスケールさせる方法や経験談などが得られやすい、というメリットもあります。  
リアルタイム性にフォーカスしたフレームワークを3つ挙げます。  
(Meteor以外は使った事が無く、ちょっと調べただけです)

  * Meteor 
    * MongoDB
    * SockJS
  * DerbyJS 
    * MongoDB(入れ替え可能)
    * Redis
    * Racer 
      * ShareJS
  * Sails 
    * Socket.IO
    * Waterline(色々なデータベースが使えるORM)

### Socket.IO

Socket.IOは上記の中では、Sailsで使われています。  
ただ、MeteorとDerbyJSはSocket.IOを避け、独自に開発したライブラリ(単独でも使えます)を使っています。  
DerbyJS(ShareJS)はSocket.IOを避ける理由として、メッセージの到着順序が保証されない事を挙げています。

### Redis

RedisはDerbyJSで使われています。  
Sailsの開発者も[古い記事](http://www.infoq.com/jp/news/2013/04/Sails-0.8.9-Released)を読むと、Redisを気に入っているようです。  
DerbyJSはMongoDBだけでなく、Redisが必要な理由として、

> クライアント同士を同期させるコードをアプリケーション(node.jsサーバ)に入れると、サーバのプロセスを増やしてスケールさせる事が出来ない。  
>  よって、データが変更された時にアプリケーションがデータベースからイベントを受ける必要がある。  
>  それにはデータベースのPubSub機能が必要で、MongoDBだとそれに制限があり、Redisが適している。  
>  ([古いFAQ](https://github.com/derbyjs/derby/wiki/Frequently-Asked-
> Questions)の大意)

としています。  
ここらへんは、データベースが必要な理由として、質問者さんは想定していなさそうですので、注意が必要かもしれません。

### Socket.IOとRedisの組合せでよいか

とりあえず、マイナーであったり、一般に悪い選択とされている、という事は無さそうですね。  
しかし、目的が経験を積む事などでは無く、アプリケーションの完成ならば、上で挙げたようなフレームワークを使う手もあります。  
サーバの面倒を見る事からも開放されたければ、FirebaseのようなBaaSを使うのもよいでしょう。


CC BY-SA 3.0
2015-11-17T08:53:14.997
18942
2015-11-17T08:53:14.997
3054
18853
answer