Live — чат и ActionCable

от автора

Хочу опубликовать коротенькую заметку о том как интегрировать, зарелизиный совсем недавно, ActionCable в ваш Ruby on Rails проект на примере Live — чата. Я не стану углубляться в то, как работает сам ActionCable, просто приведу небольшой пример использования.

Подготовка

Прежде всего добавим в Gemfile actioncable и puma:

gem 'actioncable', github: 'rails/actioncable' gem 'puma' 

ActionCable будет запускаться отдельным от основного приложения процессом. Поэтому мы будем использовать многопоточный web-сервер Puma.

Архитекутра чата

На главной странице пользователь будет вводить свой ник, после чего мы запишем его в куки и средиректим на страницу чата.

Добавим пару роутов в config/routes.rb:

resources :messages, only: [:index, :create] resources :sessions, only: [:new, :create] 

Создадим контроллеры с экшенами. Запись ника в куки:

# app/controllers/sessions_controller.rb class SessionsController < ApplicationController   def create     cookies.signed[:username] = params[:session][:username]     redirect_to messages_path   end end 

Формы авторизации пользователя app/views/sessions/new.html.slim:

= form_for :session, url: sessions_path do |f|   p     = f.label :username, 'Введите Ваш ник'   p     = f.text_field :username   p     = f.submit 'Ок' 

В самом чате пока просто будем отправлять 200 в ответ на напечатанное сообщение:

# app/controllers/messages_controller.rb class MessagesController < ApplicationController   def create     head :ok   end end 

Представление app/views/messages/index.html.slim:

p   = cookies.signed[:username] p   #messages p   = form_for :message, url: messages_path, remote: true, id: 'messages-form' do |f|     p       = f.label :body, 'Введите сообщение:'     p       = f.text_field :body     p       = f.submit 'Отправить' 

Сообщение будет отправляться AJAX’ом на сервер.

Настройка ActionCalbe

Создадим три класса, которые будут ответственны за интеграцию с ActionCable.

# app/channels/application_cable/connection.rb module ApplicationCable   class Connection < ActionCable::Connection::Base   end end   # app/channels/application_cable/channel.rb module ApplicationCable   class Channel < ActionCable::Channel::Base   end end   # app/channels/messages_channel.rb class MessagesChannel < ApplicationCable::Channel   def subscribed     stream_from 'messages'   end end 

Не забудьте добавить созданные директории в autoload_paths. Теперь, все, кто подписан на канал MessagesChannel, смогут получать сообщения по соответствующему потоку, определённому в методе subscribed, т.е. — messages.

ActionCable обеспечивает обмен сообщениями через Redis. Будем считать, что он у Вас уже установлен. Нам понадобиться настроить связь с ним в config/redis/cable.yml:

development: &dev   :url: redis://localhost:6379   :host: localhost   :port: 6379   :timeout: 1   :inline: true test: *dev production: *dev 

Теперь настроим Puma:

# cable/config.ru require ::File.expand_path('../../config/environment',  __FILE__) Rails.application.eager_load!   require 'action_cable/process/logging'   run ActionCable.server 

Запускать пуму будем на порту 34523, почему бы и нет…

# /bin/bash bundle exec puma -p 34523 cable/config.ru 

Теперь пума запускается коммандой ./bin/cable.

Отправка сообщений в общий чат

Немного подправим app/controllers/messages_controller.rb:

class MessagesController < ApplicationController   def create     ActionCable.server.broadcast 'messages',       message: params[:message][:body],       username: cookies.signed[:username]       head :ok   end end 

Самое важное — подписка на канал. Создадим два coffee файла (не забудьте прореквайрить их):

#app/assets/javascripts/channels/messages.coffee   App.messages = App.cable.subscriptions.create 'MessagesChannel',   received: (data) ->     $('#messages').append("<p><b>[#{data.username}]:</b> #{data.message}</p>")     #app/assets/javascripts/channels/index.coffee   #= require cable #= require_self #= require_tree .   @App = {} App.cable = Cable.createConsumer('ws://127.0.0.1:34523') 

Вот и всё.
Как всегда, небольшой проект — https://github.com/lon10/live-chat

ссылка на оригинал статьи http://habrahabr.ru/post/264589/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *