websocket
vue.js
Rails5
ActionCable

ActionCableとVue.jsでチャットを爆速実装

鹿児島大学でアプリ開発サークルをやっている@gakutomoです。
今回はVue.jsを使ったWebアプリケーションにチャット機能を組み込みたかったのでRailsのActionCableを使って爆速実装してみました :rocket:

ActionCableとは

WebSocketを扱うRails5の新機能
チャットのようなリアルタイムにデータ更新するアプリが作れる

こういうやつ

chat (1).gif

動作環境

クライアント側

  • macOS High Sierra
  • Google Chrome
  • Vue.js

サーバ側

  • CentOS 7
  • Rails 5.2

サーバ側の実装手順

Railsアプリケーションは作成済みとします

チャンネルの作成

console
rails g channel message

チャンネルの設定

app/channels/room_channel.rb
class MessageChannel < ApplicationCable::Channel
  # チャンネル接続時に呼ばれる
  def subscribed
    stream_from "message_channel"
  end

  # メッセージをブロードキャストするためのアクション
  def speak(data)
    ActionCable.server.broadcast 'message_channel', message: data['message']
  end
end

ルーティングを追加

config/route.rb
Rails.application.routes.draw do
  # 以下を追記
  mount ActionCable.server => '/cable'
end

クライアント側の実装手順

Vue.jsで実装します。RailsのWebPackerはうまくいかなかったので、ローカルでWebPack使って開発してます。

まず必要なパッケージをインストールします。

console
npm install actioncable

main.jsをエントリーポイントとして進めていきます

main.js
import Vue from 'vue';
import ActionCable from 'actioncable';
import Chat from './chat.vue';

const cable = ActionCable.createConsumer('ws:hoge.com:3000/cable');
Vue.prototype.$cable = cable;

new Vue({
  components: {
    Chat,
  template: '<Chat/>',
  },
}).$mount('#app');

通信部分の実装

chat.vue
<template>
  <div>
    <input v-model="msgBox" placeholder="message here"></input>
    <button v-if="messageChannel" @click="speak">送信</button>
  </div>
</template>

<script>
export default {
data() {
  return {
    msgBox: "",
    messages: [],
    messageChannel: null,
  };
},
created() {
  this.messageChannel = this.$cable.subscriptions.create( "RoomChannel",{
    received: (data) => {
      this.messages.push(data)
    },
  })
},
methods: {
  speak() {
    this.messageChannel.perform('speak', { 
      message: msgBox, 
    });
  },
},
}
</script>

ハマりどころ

  • スマホからだと以下の設定をしないと接続できなかった
  • httpsからのWebSocketはwss://にしないといけない
config/application.rb
ActionCable.server.config.disable_request_forgery_protection = true
config.action_cable.url = 'wss://hogehoge.com/cable'

参考

Rails 5 + ActionCableで作る!シンプルなチャットアプリ
railsとvueでリアルタイムな注文システムを作ってみた
ActionCable の README を読んでチャットアプリを作ってみた
フロントエンドで ActionCable を npm 経由で使う
Action Cable でプログレスバーを更新する