Edited at

Rails + ActionCable + ReactJS(ES6)でリアルタイムチャットアプリを作った

More than 3 years have passed since last update.

リアルタイムチャットアプリのようなインタラクティブなWEBアプリケーションを作りたくて、情報収集していた所に、Rails5からActionCableというwebsocketを簡単に扱える仕組みが導入されると聞いて、早速試してみたのでその感想を書いていきます。


作ったサンプルアプリ

https://github.com/iguchi1124/actioncable-react-chat-sample


ActionCable

ActionCableはRails5から導入されるWebSocketの実装。

これを用いれば既存のWEBアプリケーションにも簡単にWebSocket使った環境を導入できる。

ちなみにRails4以前の開発ではEventMachineをつかったWebsocketの実装である

https://github.com/igrigorik/em-websocket

こちらを使っている例がちらほら見られていた。


react-rails

https://github.com/reactjs/react-rails

チャットアプリは基本的にDOMの変化が激しいので、その辺りのDOMの管理を効率的に行うためにフロントエンドフレームワークを使う。

react-railsを用いればサーバーサイドレンダリングとreact.jsによるDOM操作を共存させることができるすぐれもの。


sprocket-es6

https://github.com/TannerRogalsky/sprockets-es6

babelを用いてES6をES5にコンパイルできるようにするGem。

ただし、Rails5以降ではES6がデフォルトで扱えるようになる。


実装

バックエンドの実装は公式のactioncable-examplesとほぼ同じなので割愛。


app/assets/javascripts/channels/index.es6

//= require cable

//= require_self
//= require_tree .

let App = {};
App.cable = Cable.createConsumer('ws://localhost:28080');


react-railsが提供するジェネレータでmessageコンポーネントを生成して編集する。

下記コマンドで生成できる。

$ rails g react:component [ComponentName] --es6


app/assets/javascripts/components/message.es6.jsx

class Messages extends React.Component {

constructor() {
super()
this.state = {messages: []}
}

render() {
return (
<div className='messages'>
{this.state.messages.map(function (message, i) {
return <p key={i}><b>{message.sender}:</b>{message.content}</p>
})}
</div>
)
}

componentDidMount() {
this.setupSubscription()
}

updateMessage(message) {
this.setState({
messages: this.state.messages.concat({
sender: message.sender, content: message.content
})
})
}

setupSubscription() {
App.cable.subscriptions.create('MessagesChannel', {
received(message) {
return this.updateMessage(message)
},
updateMessage: this.updateMessage.bind(this)
})
}
}



参考URL

WebSocketについて調べてみた。

Using ReactJS with Rails Action Cable