Notification with actioncable
Bài đăng này đã không được cập nhật trong 7 năm
Ngày hôm nay mình xin giới thiệu về 1 kĩ thuật được hỗ trợ rất mạnh từ bản Rails 5, đó là Action Cable. Cụ thể mình sẽ hướng dẫn các bạn sử dụng tính năng này để thực hiện chức năng thông báo trong ứng dụng realtime.
Trước hết chúng ta cùng tìm hiểu qua một số khái niệm cơ bản
1. Websocket
Websocket là một công nghệ dùng để hỗ trợ cho việc giao tiếp hai chiều giữa Sever và Client thông qua việc sử dụng một TCP Socket nhằm tạo ra một liên kết hiệu quả mà lại ít tốn kém.
Websocket là một tính năng đặc biệt trong HTML5 sử dụng kỹ thuật Reverse Ajax, nó cho phép các kênh giao tiếp chạy song song hai chiều và hiện tại đã được rất nhiều trình duyệt hỗ trợ (Firefox, Google Chrome và Safari)
-
Ưu điểm
- Đối với WebSockets việc cung cấp tới khả năng giao tiếp hai chiều rất mạnh mẽ, có độ trẽ thấp cũng như dẽ dàng xử lý khi phát sinh lỗi
- Dung lượng của một kết nối bằng WebSocket sẽ ít hơn rất nhiều so với một HTTP Request.
-
Nhược điểm
- Do WebSocket là một tính năng đặc biệt của HTML5 chính vì thế nó vẫn chưa nhận được sự hỗ trợ của tất cả các trình duyệt.
2. Action Cable
Action Cable là một tính năng tích hợp WebSocket của Rails. Sử dụng Javascript ở phía Client và Ruby ở phía Server. Cho phép lập trình viên có thể sử dụng nhiều mục đích, chủ yếu là realtime.
Vậy là mình đã giới thiệu qua một số khái niệm cơ bản về Action Cable, và sau đây mình sẽ hướng dẫn cách gửi nhận dữ liệu để thực hiện chức năng thông báo trong ứng dụng Rails.
3. Notification
- Server
#app/channels/apllication_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
protected
def find_verified_user
if verified_user = env["warden"].user
verified_user
else
reject_unauthorized_connection
end
end
end
end
Khi Client gửi một yêu cầu kết nối tới Server thì đầu tiên nó sẽ thực hiện hàm connect.
Ở đây, mình sử dụng hàm connect để thực hiện chức năng tìm user trong database tương ứng với chính Client đang yêu cầu kết nối. Nếu không tìm thấy sẽ hủy kết nối
Tiếp theo, tạo một kênh ứng với mục đích sử dụng của mình. Ở đây mình đặt tên là NotificationChannel.
#app/channels/notification_channel.rb
class NotificationChannel < ApplicationCable::Channel
def subscribed
channel_name = "#{current_user.email}_notification_channel"
stream_from channel_name
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def speak data
end
end
Sau khi yêu cầu từ Client đã được chấp nhận, thì Server sẽ thực hiện hàm subscriebed để thực hiện tạo một kênh riêng để trao đối dữ liệu với Client
Hàm unsubscribed để hủy bỏ kênh
Hàm speak là hàm nhận dữ liệu gửi lên từ Client cho Server. Tại đây, ta có thể xử lí dữ liệu Client gửi lên.
Tiếp theo, ta sẽ tạo một job để chuyên đảm nhiệm việc gửi notification, việc này giúp tiến trình gửi notification không ảnh hưởng tới các thao tác khác của ứng dụng.
class NotificationJob < ApplicationJob
queue_as :default
def perform args
ActionCable.server.broadcast ten_kenh, {du lieu}
#ten_kenh = {current_user.email}_notification_channel"
end
end
Ở đây có 2 dữ liệu ta cần truyền vào để có thể gửi dữ liệu về Client.
Thứ nhất là ten_kenh, ở ví dụ này là "{current_user.email}_notification_channel"
Tiếp theo là dữ liệu: {Dữ liệu mà ta muốn truyền}. Ví dụ: {notification: @notification}
Vậy là đã xong công việc bên server.
- Client
#app/assets/javascripts/cable/notification.js
App.notification = App.cable.subscriptions.create({
channel: 'NotificationChannel'}, {
received: function(data) {
},
speak: function(data) {
this.perform('speak', data);
}
});
App.notification.speak(du_lieu);
});
});
Tạo kết nối tới kênh mà ta muốn kết nối. Ở đây là NotificationChannel.
Dữ liệu nhận về sẽ thông qua biến data ở hàm received.
App.notification.speak(du_lieu): Để gửi dữ liệu lên server.
Vậy là đã xong công việc thao tác gửi nhận rồi
Cảm ơn mọi người đã đọc. Bài viết sẽ không thiếu những sai xót, mong mọi người đóng góp yk bên dưới
All rights reserved