액션 케이블과 웹소켓
Biweekly Lecture
2015-07-28
Ruby on Rails Korea
- ROR Lab. Season 4 -

순서
- 개요
- 젬 추가
- 테스트 뷰 작성
- 액션케이블 설정(메시지 채널 등)
- 메시지를 스트림으로 전달
- 웹브라우저가 메시지를 수신
- 참고자료
액션케이블 개요
What is ActionCable:
- 레일스5의 새로운 주요 기능
- 실시간으로 상호작용하기 위한 라이브러리
- 채팅 앱 예시

필요한 젬 추가 Gemfile
- puma/thin 멀티 쓰레드 필요(웹서버와 별도 실행)
- unicorn 도 사용할 수 있으나 추천하지 않음
- 레일스 4.2에서도 액션케이블을 사용할 수 있음
- 레일스 5(깃헙) 사용할 경우 루비버전 2.2.2 이상필수

source 'https://rubygems.org'
gem 'rails', '4.2.3'
gem 'actioncable', github: 'rails/actioncable'
gem 'sqlite3'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'puma'
gem 'uglifier', '>= 1.3.0'
group :development, :test do
gem 'byebug'
gem 'spring'
gem 'web-console', '~> 2.0'
end테스트 뷰 작성



테스트 뷰 작성
-
SessionsController 첫화면(채팅 유저네임을 입력)
- create(입력 선택하여 채팅창으로 들어감)
-
MessagesController 채팅 창(유저네임과 메시지 표시)
- index(채팅 창), create(메시지 생성)
- route.rb 첫화면 session#new
- app/views/sessions/index.html.erb 유저네임 선택
- app/views/messages/index.html.erb form_for remote 옵션

테스트 뷰 작성(session)
-
MessagesController 채팅 창(유저네임과 메시지 표시)
- index(채팅 창), create(메시지 생성)
-
SessionsController 첫화면(채팅 유저네임을 입력)
- create(입력 선택하여 채팅창으로 들어감)

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
cookies.signed[:username] = params[:session][:username]
redirect_to messages_path
end
end<%= form_for :session, url: sessions_path do |f| %>
<%= f.label :username, 'Enter a username' %><br/>
<%= f.text_field :username %><br/>
<%= f.submit 'Start chatting' %>
<% end %>테스트 뷰 작성(message)
- remote: true 이 옵션으로 화면 새로고침하지 않고 비동기 자바스크립트 통신(AJAX) 함.
- #messages div 엘리멘트에 채팅 메시지 계속 추가

class MessagesController < ApplicationController
def create
head :ok
end
endSigned in as @<%= cookies.signed[:username] %>.
<br/><br/>
<div id='messages'></div>
<br/><br/>
<%= form_for :message, url: messages_path, remote: true, id: 'messages-form' do |f| %>
<%= f.label :body, 'Enter a message:' %><br/>
<%= f.text_field :body %><br/>
<%= f.submit 'Send message' %>
<% end %>액션케이블 설정
레일스 프로젝트에 사용자 직접 만들어야 하는 파일
- app/channels/application_cable/connection.rb
- app/channels/application_cable/channel.rb
- config/redis/cable.yml 레디스로 (PUBLISH/SUBSCRIBE)
- cable/config.ru 웹애플리케이션과 별도 실행하기 위한 Rackup파일
- bin/cable 긴 명령어를 줄여서 실행하는 배시 스크립트
- app/channels/messages_channel.rb

액션케이블(channel, redis)

# 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
endlocal: &local
:url: redis://localhost:6379
:host: localhost
:port: 6379
:timeout: 1
:inline: true
development: *local
test: *local액션케이블(rackup)

# cable/config.ru
require ::File.expand_path('../../config/environment', __FILE__)
Rails.application.eager_load!
require 'action_cable/process/logging'
run ActionCable.server# /bin/bash
bundle exec puma -p 28080 cable/config.ru액션케이블(messages)

# app/channels/messages_channel.rb
class MessagesChannel < ApplicationCable::Channel
def subscribed
stream_from 'messages'
end
end메시지 전달
레일스 프로젝트에 사용자 직접 만들어야 하는 파일
- app/channels/application_cable/connection.rb
- app/channels/application_cable/channel.rb
- config/redis/cable.yml 레디스로 (PUBLISH/SUBSCRIBE)
- cable/config.ru 웹애플리케이션과 별도 실행하기 위한 Rackup파일
- bin/cable 긴 명령어를 줄여서 실행하는 배시 스크립트
- app/channels/messages_channel.rb

class MessagesController < ApplicationController
def create
ActionCable.server.broadcast 'messages',
message: params[:message][:body],
username: cookies.signed[:username]
head :ok
end
end웹브라우저가 메시지를 수신
- app/assets/javascripts/channels/index.coffee 웹소켓 서버 연결
- app/assets/javascripts/channels/messages.coffee
- received 콜백은 메시지를 수신하고 JSON으로 넘어온 데이터에서 유저네임과 메시지를 div 엘리먼트에 추가한다.

# app/assets/javascripts/channels/index.coffee
#= require cable
#= require_self
#= require_tree .
@App = {}
App.cable = Cable.createConsumer 'ws://127.0.0.1:28080'# app/assets/javascripts/channels/index.coffee
App.messages = App.cable.subscriptions.create 'MessagesChannel',
received: (data) ->
$('#messages').append @renderMessage(data)
renderMessage: (data) ->
"<p><b>[#{data.username}]:</b> #{data.message}</p>"참고자료
- 예시 프로젝트(니딘베칼 nithinbekal)
- http://nithinbekal.com/posts/rails-action-cable
-
레일스 5버전으로 만든 액션 케이블 예시 소스(니딘베칼)
-
https://github.com/nithinbekal/actioncable-chat-example
-
-
레일스 5 를 사용할 경우 젬 파일 구성
-
https://github.com/nithinbekal/actioncable-chat-example/blob/f0f4c7269c0c491576fd23db4fd11c09ebe69f54/Gemfile
-
-
액션케이블 소스 저장소
-
https://github.com/rails/actioncable
-
-
레일스 개발 팀이 공개한 액션 케이블 예시
-
https://github.com/rails/actioncable-examples
-
-
고 레일스(동영상) 레일스 개발팀의 액션 케이블 예시를 설명
-
https://gorails.com/episodes/rails-5-actioncable-websockets
-
-
래피드파이어(설문조사) 관련 액션케이블 예시
-
https://github.com/code-mancers/rapidfire-demo/compare/actioncable
-

간단한 채팅 애플리케이션
데모
감사합니다
액션케이블과 웹소켓 ActionCable and Websocket
By wagurano
액션케이블과 웹소켓 ActionCable and Websocket
액션케이블과 웹소켓 ActionCable and Websocket
- 2,308