Edited at

websocket-railsで簡単なPush通知を実装する

More than 5 years have passed since last update.

websocket-railsを使ってRailsでWebSocketによるPush通知を実装する話をします。

websocket-railsを使って簡単なデモを作ってHerokuにアップしました。Twitter Streaming APIで受け取ったデータをWebSocketでリアルタイムにクライアントへ送るものです。ソースコードもgithubにありますので参考にどうぞ。


セットアップ


Gemfile

gem "websocket-rails"


$ bundle

$ rails g websocket_rails:install

最後のコマンドで設定ファイルを追加し、application.jsをクライアント側のライブラリをrequireするように変更します。

開発環境ではRack::Lockを無効にしないとエラーになるので以下のようにしておきます。


config/environments/development.rb

TwitterStreamingSample::Application.configure do

config.middleware.delete Rack::Lock
end


実装

WebSocket接続したクライアントに対して任意のタイミングでメッセージを送りたい場合、channelというものを使うと簡単に実装できます。


streamings_controller.rb

def create

# ...
WebsocketRails[:streaming].trigger "create", tweet
head :ok
end

これで、"streaming"というチャネルに"create"というメッセージをtweetのデータとともに送信します。WebSocketRailsという定数はどこからでもアクセス可能なので、任意のタイミングでチャネルにメッセージを送ることが可能です。


streamings.js.coffee

dispatcher = new WebSocketRails("ws://#{localhost.host}/websocket")

channel = dispatcher.subscribe("streaming")
channel.bind "create", (tweet) ->
# something

次にクライアント側では、まずWebSocket接続を行います。WebSocket接続はwebsocket-railsが追加する/websocketというパスに対してリクエストを送ります。

接続が成功するとdispatcherと呼ばれるオブジェクトを返します。このオブジェクトはWebSocketサーバーとやり取りをする中心的なオブジェクトです。dispatcher#subscribe(チャネル名)で特定のチャネルを購読するオブジェクトを取得できるので、あとはメッセージを受け取ったときのコールバックを設定するだけです。


これだけ

これだけでdispatcherでsubscribeしたクライアントすべてに対してRailsからPush通知ができます。


nginx

本番環境でnginxとともに運用する場合、nginx側の設定も必要です。nginxでWebSocketのプロキシを行うには1.3.13以降であることが必要です。


nginx.conf

location /websocket {

proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}

"Upgrade"というヘッダーはプロトコルをHTTPからWebSocketに変更するために必要な情報で、RFCで定められています。


Heroku

最近、HerokuがWebSocketのサポートを開始しました。ただし、まだβ版での開始なので、デフォルトのままではWebSocketを利用できません。以下のコマンドを実行するとWebSocketの機能がオンになります。

$ heroku labs:enable websockets



参考