Jump to content

The ultimate community for Ruby on Rails developers.


Photo

How to control/limit Action Cable Subscriptions per user?

Action Cable Rails 5 Pub/Sub WebSockets Push Notifications Web Notifications

  • Please log in to reply
No replies to this topic

#1 JLGarofalo

JLGarofalo

    Passenger

  • Members
  • 1 posts

Posted 09 November 2016 - 02:32 PM

# Problem

I'm trying to create a Desktop Notification feature in my RoR application using Action Cables. My typical user will have multiple panes open at any given time which presents me with a unique obstacle. A single user may have `n` windows/panes open, meaning `n` consumers. This means that any one event will trigger `n` identical Desktop Notifications, which provides a poor user experience. 
 
I could reject any request to connect after the first but this would mean that any future Action Cable features I build will also only be available to the first window/pane which is no good.
 
# Code
    # app/channels/application_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 current_user = User.find(cookies.signed[:user_id])
            current_user
          else
            reject_unauthorized_connection
          end
        end
      end
    end
-------------
    # app/assets/javascripts/channels/desktop_notifications.js
    
    App.cable.subscriptions.create(
      'DesktopNotificationsChannel',
      {
        connected: function() {
          console.log('subscribed to DesktopNotificationsChannel');
    
          if(!("Notification" in window)) {
            console.warn("Notifications aren't supported in this browser");
          } else if (Notification.permission === "granted") {
            console.log("Notification Status: " + Notification.permission);
          } else {
            Notification.requestPermission()
              .then((result) => {
                console.log('Notification Status: ' +  result);
              });
          }
        },
    
        disconnected: function() {
          console.log('unsubscribed to DesktopNotificationsChannel');
        },
    
        received: function(data) {
          console.log(data);
          const {
            body,
            destinations,
            image_url: imageUrl,
            title,
          } = data;
    
          var options = {
            body: body,
            icon: imageUrl,
          };
    
          var notification = new Notification(title, options);
    
          if (destinations) {
            notification.onclick = (event) => {
              event.preventDefault();
    
              destinations.map((destination) => {
                window.open(destination, '_blank');
                window.focus();
              });
            }
          }
        },
      }
    );
----------------
    # app/channels/desktop_notification_channel.rb
    
    class DesktopNotificationsChannel < ApplicationCable::Channel
      def subscribed
        stream_from 'desktop_notifications'
      end
    end
-----------------
 # app/operations/desktop_notifications/desktop_notification.rb
    
    module DesktopNotifications
      class DesktopNotification
        def initialize
        end
    
        def broadcast
          ActionCable.server.broadcast(
            'desktop_notifications',
            title: title,
            body: @body,
            image_url: logo_url,
            destinations: destinations
          )
        end


        # some other helpers
      end
    end
--------------------
 
Essentially I want something that will let me control a user's subscriptions and only display one Push Notification per user while still being able to broadcast to all of the users who are subscribed (think User-specific mutex for a subscription). 
 
Any ideas would be greatly appreciated! 






Also tagged with one or more of these keywords: Action Cable, Rails 5, Pub/Sub, WebSockets, Push Notifications, Web Notifications

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users