Nguyen Anh bio photo

Nguyen Anh

A VietNam web developer

Email Facebook Github

Some gem

fastgem block_templates

Một tính năng đáng chú ý của phiên bản Rails 5 đó là tích hợp ActionCable. Nhiệm vụ của ActionCable là cho phép chúng ta có thể tạo chức năng real-time trong các ứng dụng Rails trở nên đơn giản hơn rất nhiều.

ActionCable sử dụng giao thức Websocket để hỗ trợ giao tiếp 2 chiều giữa client và server.

Bài viết này để sẽ hưỡng dẫn step-by-step để tạo 1 ứng dụng web chat real-time sử dụng tính năng Action-Cable có săn trong Rails 5.

Yêu cầu Có sẵn: * Ruby 2.2.2 trở lên. * Rails 5.

Step 1: Tạo một ứng dụng với Rails 5.

rails new chat-action-cable --skip-spring
cd chat-action-cable

Step 2: Tạo trang để chưa nội dung messages.

rails g controller rooms index

Set mặc định hệ thống sẽ truy cập đến rooms#index.


#router.rb
root to: "rooms#index"

Step 3: Tạo model để kết nối DB chứa dữ liệu.


rails g model message content:text
rake db:migrate

Tiếp theo lấy tất cả data messages trong rooms_controller


#rooms_controller
def index
    @messages = Message.all
end

Tạo một _message.html.erb trong thư mục app/views/messages

mkdir app/views/messages
touch app/views/messages/_message.html.erb

#app/views/messages/_message.html.erb
<div class='message'>
  <p><%= message.content %></p>
</div>

#app/views/messages/_message.html.erb
<h1>Rooms</h1>
<div id="messages">
  <%= render @messages %>
</div>
<%= text_field_tag :body, "", id: "chat-speak" %>

step 4: Tạo một channel để giao tiếp giữa server và client.


rails g channel room speak

Tiếp theo ta cấu hình cho channel vưa tạo. Cấu hình cho client.


# app/assets/javascripts/channels/room.coffee
App.room = App.cable.subscriptions.create "RoomChannel",
  connected: ->
    # Method này sẽ được gọi khi đã kết nối với RoomChannel.

  disconnected: ->
    # Method này sẽ được gọi khi đã kết thúc kết nối với RoomChannel.

  received: (data) ->
    $('#messages').append data['message']
    #Show messges khi nhận dữ liệu từ server trả về.

  speak: (message) ->
    @perform 'speak', message: message
    # Dùng để thông báo với server là có dữ liệu truyền lên.

  $(document).on 'keypress', '#chat-speak', (event) ->
    if event.keyCode is 13 # return = send
      App.room.speak event.target.value, 
      event.target.value = ""
      event.preventDefault()

Cấu hình cho server.


# app/channels/room_channel.rb
class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_channel"
  end

  def unsubscribed
  end

  def speak(data)
    Message.create! content: data['message']
  end
end

Step 5: Tạo 1 con job để thực hiện việc response cho client.


rails g job MessageBroadcast

Ta sẽ sử dụng Callbacks của Active Record để gọi Jobs thực hiện response cho client.

#models/message.rb
class Message < ApplicationRecord
  after_create_commit { MessageBroadcastJob.perform_later self }
end
#jobs/message_broadcast_job.rb
class MessageBroadcastJob < ApplicationJob
  queue_as :default

  def perform(message)
    #Response về cho client.
    ActionCable.server.broadcast 'room_channel', message: render_message(message)
  end

  private
    def render_message(message)
      ApplicationController.renderer.render(partial: 'messages/message', locals: { message: message })
    end
end

Như vậy là đã xong phần code một trang web chat real-time. Giờ bạn có thể chạy ứng dụng rails s, và mở nhiều browser khác nhau để xem kết quả.