Skip to content
This repository has been archived by the owner on May 18, 2023. It is now read-only.

vivekmiyani/offline_broadcaster

Repository files navigation

OfflineBroadcaster

  • This gem aims to deliver messages/data or save into database for later delivery to the receiver according to their (online/offline) status.
  • The main advantage to use this gem is that we can eliminate message delivery logic from our application code. So we can directly do broadcast without worrying about the user status.

Installation

Add this line to your application's Gemfile:

gem 'offline_broadcaster'

And then execute:

$ bundle install

Install migration yourself (as of now):

class CreateOfflineBroadcasterRecords < ActiveRecord::Migration[6.1]
  def change
    create_table :offline_broadcaster_records do |t|
      t.references :receiver, polymorphic: true
      t.string     :channel
      t.json       :data

      t.timestamps
    end
  end
end

Run migration:

$ rails db:migrate

Usage

Create Adapter to listen for the messages:

  • It should inherit OfflineBroadcaster::Adapter (It can be placed inside model or wherever you want).
  • Overload collect method as below example.
  • So, whenever user receives a message this method will be called. Like, for online users it will be called immediately and for offline users it will be called once user comes online.
class User::OfflineManager < OfflineBroadcaster::Adapter

  # This method called when user comes online.
  def self.collect(channel:, receiver:, data:)
    # Here we can safely publish message to redis channel
    # OR we can publish it on ActionCable channel.
  end
end

Add this to your User model:

  • While calling acts_as_offline_receiver pass online_attribute so gem can identify user status (In our case we have online column in our database).
  • And also need to pass adapter we just wrote.
class User < ApplicationRecord
  acts_as_offline_receiver online_attribute: :online, adapter: User::OfflineManager
end

Let's test it:

receiver = User.last
receiver.online
# => false

# Send a message
User::OfflineManager.deliver(channel: 'greeting_channel', receiver: receiver, data: 'Hello online user!!')
User::OfflineManager.deliver(channel: 'greeting_channel', receiver: receiver, data: { message: 'Welcome!!' })
# => # Some insert query will going to run.

# Update the user status
receiver.update(online: true)
# => User::OfflineManager#collect will be called.

How it works?

  1. This gem will observe the given attribute changes (to identify user online/offline status).
  2. While sending a message if user is online then that message will be delivered immediately
  3. Otherwise, it will store that into database and when user comes online again those pending messages will be delivered.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/vivekmiyani/offline_broadcaster. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the OfflineBroadcaster project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.