+2

Notification with actioncable

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

Viblo
Let's register a Viblo Account to get more interesting posts.