Online/offline appearance realtime với Actioncable trong Rails 5
Bài đăng này đã không được cập nhật trong 6 năm
Introduction
Actioncable là tính năng mới của Rails 5 nhờ sử dụng websocket để tạo realtime application một cách đễ dàng và nhanh chống, cho phép server và client tương tác với nhau realtime. Hôm này mình sẽ đưa ra một ví dụ về cách sử dụng actioncable để tạo Online/offline appearance cho người dùng hệ thống. Về phần đầu tiên để config, tạo channel hoặc cách làm việc của actioncable thế nào mình sẽ không nói ở đây nữa. Nếu bạn chưa làm quên với nó, có thể tham khảo một số tài liệu sau: https://github.com/rails/rails/tree/master/actioncable https://blog.heroku.com/real_time_rails_implementing_websockets_in_rails_5_with_action_cable
Let's start!
- Tạo migration them column
online:boolean
mới vào bảnguser
(hoặc bảng khác tùy thuộc vào project của bạn). Trường này dùng để lưu appearance của user để biết là đang online hay không.
class AddOnlineToUser < ActiveRecord::Migration[5.0]
def change
add_column :users, :online, :boolean, default: :false
end
end
chạy migrate:
rake db:migrate
- Tạo list user cùng với status online/offline:
# app/controllers/rooms_controller.rb
def show
@users = User.page(params[:page]).per 10
end
<ul id="users-list">
<% @users.each do |member| %>
<li>
<%= member.name %>
<% if member.online %>
<%= image_tag "green_dot.png", id: "#{member.user_id}-status", class: "active" %>
<% else %>
<%= image_tag "green_dot.png", id: "#{member.user_id}-status", class: "inactive" %>
<% end %>
</li>
<% end %>
</ul>
Styles css:
/* app/assets/stylesheets/main.css */
.active { display: ; } .inactive { display: none; }
- Tạo appearance channel: Khi user join vào hệ thống (subscribe) thì mình sẽ update online: true. Khi user ra khỏi hệ thống (unsubscribe) thì mình sẽ update online: false.
rails g channel appearance
Channel sẽ có như sau:
#app/channels/appearance_channel.rb
class AppearanceChannel < ApplicationCable::Channel
def subscribed
member = User.where(user_id: current_user.id).first
return unless member
member.update_attributes(online: true)
stream_from "appearance_user"
end
def unsubscribed
member = User.where(user_id: current_user.id).first
return unless member
member.update_attributes(online: false)
end
end
- Tạo job để publish data: sau khi user thay đổi status online thành true/false, chúng ta sẽ publish data tới client để cập nhật lại hình ảnh active (green dot) hoặc không active (không hiện green dot).
rails g job AppearanceBroadcast
#app/jobs/appearance_broadcast_job.rb
class AppearanceBroadcastJob < ApplicationJob
queue_as :default
def perform(user)
ActionCable.server.broadcast "appearance_user", render_json(user)
end
private
def render_json(user)
ApplicationController.renderer.render(json: user)
end
end
# app/models/user.rb add this right under the validations
after_update_commit {AppearanceBroadcastJob.perform_later self}
Sau khi server đã publish data, bên client sẽ nhận được đã data đó và phải xử lý cập nhật lại hình ảnh active (green dot) hoặc không active (không hiện green dot).
// app/assets/javascripts/channels/appearance.js
App.appearance = App.cable.subscriptions.create({
channel:'AppearanceChannel'
}, {
received: function(data) {
var user = JSON.parse(data)
if (user.online === true){
$(userImgIdConstructor(user)).attr('class', 'active');
};
if (user.online === false){
$(userImgIdConstructor(user)).attr('class', 'inactive');
};
}
});
var userImgIdConstructor = function(user){
return "#" + user.user_id + "-status";
}
Conclusion
Done! Bây giờ chúng ta đã làm xong về việc tạo online/offline status cho hệ thông của mình. Bạn thấy rằng nhờ sử dụng actioncable thì việc tạo realtime application không phải là vấn đề khó khăn nữa.
All rights reserved