チャットやオンラインゲームなどのアプリではリアルタイム通信機能が必要になります。実装の難易度が高そうに感じられるかもしれませんが、Monacaアプリで使われるHTML5であれば、WebSocketという技術を使うことで比較的簡単に実現できます。

こちらの記事ではWebSocketの概要と、その導入方法について紹介します。

WebSocketとは

WebSocketは読んで字のごとく、Web上でソケット通信を実現する技術になります。これまでのHTTP通信では一回の接続ごとに情報が送受信されて切断される仕組みでした。そのため、サーバ側からクライアントに対して情報を送る(プッシュする)のが困難でした。

サーバ側から情報をプッシュする技術として、WebSocket登場以前にも幾つかの方法がありました。

multipart/x-mixed-replace

Firefoxの前身であるWebブラウザ、Netscapeを開発していたNetscape社が実装していたサーバプッシュ方式です。Webカメラの映像を書き換える際など、MJPEG over HTTPに使われています。IEでは実装されていません。

Java/Flash

JavaやFlashといったプラグインを使った技術でもリアルタイム通信機能が実現されていました。ともあれ、HTML5の時代になってプラグインは使われないようになっていますので過去の技術になってしまっています。

Comet

ロングポーリングと呼ばれる手法でHTTP接続を長時間持続させつつサーバ側からメッセージを送信、さらに再接続します。ただしコネクションが張り続けられることになるので大量のクライアントからの接続に対応するのは難しいと言えます。

実装方法について

こうした歴史がある中で、HTML5の時代になって生み出されたのがWebSocketになります。プロトコルはwsまたはwss(WebSockets over SSL/TLS)を指定します。JavaScriptで書くと次のようになります。

処理はすべてコールバックで実装していきます。

基本的にはテキストメッセージを送るかと思いますが、最新の仕様ではバイナリも送受信できるようになっています(参考:WebSocket の導入: ウェブにソケットを実装する – HTML5 Rocks)。

JSONを送る場合には文字列に変換する必要があります。

逆にメッセージを受け取った方ではJSON.parseを使って文字列からJSONオブジェクトに変換します。

WebSocketサーバを用意する

WebSocket通信を行う際には通常のWebサーバに変わる、WebSocketサーバを用意しなければなりません。有名なところとしては下記があります。

元々Node.jsが出てきた時にチャット実装が目立っていたこともあってNode.jsによる実装がよく見かけられます。ついでEventMachineを使ったRubyベースのWebSocketサーバも数多くあります。なお、Ruby on Rails5からはAction Cableという機能によって簡単にWebSocketが使えるようになっています。セッションデータ(実際にはCookieを利用)も使えるので、認証情報をWebサーバ側と共通で利用できます。もしRuby on Railsでシステムを構築しているならば別途WebSocketサーバを立てるのではなくAction Cableを使うのが手軽でしょう。

WebSocketを別サーバで立てる場合、最も簡単に立てられるのがHerokuを使った方法になります。今回は heroku-examples/ruby-websockets-chat-demo を使って紹介します。これはRubyベース、faye-websocketを使ったWebSocketサーバになります。

本記事公開時点で、Ruby 2.1が非サポートとなったことにより上記アプリケーションがデプロイできなくなったようです。
Ruby 2.2系にアップデートしたものを用意しましたので、こちらをご利用ください。

デプロイについて

ruby-websockets-chat-demo のデプロイはとても簡単です。goofmint/ruby-websockets-chat-demoに行き、[Deploy to Heroku] をクリックするだけです。

こちらにそのライブデモサーバがあります

すぐにメッセージを送ることができます。

フロントエンドについて

まずこの仕組みですが、トップページにてapplication.jsが読み込まれています。この中でWebSocketのコネクションを有効にしています。

後はメッセージを受け取った時に画面に描画するコードがあります(分かりやすいように一部修正)。

さらにチャットの送信イベントがあります。

これらの処理をMonacaアプリで実装すれば同じようにチャット機能が使えます。より適切な実装としては ws.onclose(接続が閉じられた際のイベント)が呼ばれた際にはsetIntervalを使って定期的に接続し直すのが良いでしょう。

バックエンドについて

次にバックエンドの実装は ruby-websockets-chat-demo/chat_backend.rb at master · heroku-examples/ruby-websockets-chat-demo が参考になります。

この例では faye-websocket を使っていますので、Faye::WebSocket.new にてWebSocketサーバを立てます。後はJavaScript側と同じようにopen/message/closeといった各イベントについて処理を実装していきます。このチャットデモではデータをRedisに保存しています。

このチャットデモはHerokuにデプロイしていますが、もちろん自社のサーバにデプロイもできます。その際にはRedisのインストールをし、次のようにコマンドを実行します。 .env.sample を参考に、RedisのURLやWebサーバのポート番号の変更を忘れずに行ってください。


WebSocketサーバはWebサーバとは別で立ち上げる必要があるので敷居が高いと感じるかも知れません。また、安定的に稼働し続けるためには運用上の慣れも必要です。しかしリアルタイム通信機能を組み込むことでより発展的なアプリを開発することができます。今回の記事が皆様のお役に立てば幸いです。

次回は、WebSocketサーバを利用してMonacaでチャットアプリを作る内容を予定しています。今回軽く触れたフロントエンドの処理について詳しく解説しますので、ご期待ください。