Last active
July 24, 2022 11:10
-
-
Save leastbad/7c5f2896d4ab3002ee2e18efbc6861d5 to your computer and use it in GitHub Desktop.
Action Cable Channels setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ApplicationCable | |
class Channel < ActionCable::Channel::Base | |
include CableReady::Broadcaster | |
delegate :render, to: :ApplicationController | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ApplicationCable | |
class Connection < ActionCable::Connection::Base | |
identified_by :session_id, :current_user | |
def connect | |
env["warden"].authenticated? | |
self.current_user = env["warden"].user | |
self.session_id = request.session.id | |
# this assumes that you want to enable SR for unauthenticated users | |
reject_unauthorized_connection unless current_user || session_id | |
# if you want to disable SR for unauthenticated users, comment out the line above and uncomment the line below | |
# reject_unauthorized_connection unless current_user | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Users::RegistrationsController < Devise::RegistrationsController | |
def create | |
old_session_id = session.id.to_s | |
build_resource(sign_up_params) | |
resource.save | |
if resource.persisted? | |
session.options[:id] = session.instance_variable_get(:@by).generate_sid | |
session.options[:renew] = false | |
set_flash_message! :notice, :signed_up | |
sign_up(resource_name, resource) | |
cable_ready[SessionsChannel].dispatch_event(name: "reconnect").broadcast_to(request.session.id) | |
ActionCable.server.remote_connections.where(session_id: old_session_id, current_user: nil).disconnect | |
respond_with resource, location: after_sign_up_path_for(resource) | |
else | |
clean_up_passwords resource | |
set_minimum_password_length | |
respond_with resource, status: 400 | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CableReady from 'cable_ready' | |
import consumer from './consumer' | |
let reconnecting = false | |
consumer.subscriptions.create('SessionChannel', { | |
received (data) { | |
if (data.cableReady) | |
CableReady.perform(data.operations, { | |
emitMissingElementWarnings: false | |
}) | |
}, | |
connected () { | |
reconnecting = false | |
document.addEventListener('reconnect', this.reconnect) | |
}, | |
disconnected () { | |
document.removeEventListener('reconnect', this.reconnect) | |
if (reconnecting) setTimeout(() => consumer.connect(), 25) | |
}, | |
reconnect () { | |
reconnecting = true | |
consumer.disconnect() | |
} | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SessionChannel < ApplicationCable::Channel | |
def subscribed | |
stream_for session_id | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Users::SessionsController < Devise::SessionsController | |
def create | |
prev_session_id = session.id.to_s | |
super do | |
session.options[:id] = session.instance_variable_get(:@by).generate_sid | |
session.options[:renew] = false | |
cable_ready[SessionsChannel].dispatch_event(name: "reconnect").broadcast_to(request.session.id) | |
ActionCable.server.remote_connections.where(session_id: prev_session_id, current_user: nil).disconnect | |
end | |
end | |
def destroy | |
prev_session_id = session.id.to_s | |
old_user = current_user | |
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)) | |
set_flash_message! :notice, :signed_out if signed_out | |
cable_ready[SessionsChannel].dispatch_event(name: "reconnect").broadcast_to(request.session.id) | |
ActionCable.server.remote_connections.where(session_id: prev_session_id, current_user: old_user).disconnect | |
redirect_to after_sign_out_path_for(resource_name) | |
end | |
private | |
def verify_signed_out_user | |
if all_signed_out? | |
set_flash_message! :notice, :already_signed_out | |
redirect_to after_sign_out_path_for(resource_name) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import consumer from './consumer' | |
import CableReady from 'cable_ready' | |
let channel | |
document.addEventListener('turbo:load', () => { | |
if (channel) return | |
channel = consumer.subscriptions.create('UsersChannel', { | |
received (data) { | |
if (!data) channel = undefined | |
if (data.cableReady) CableReady.perform(data.operations) | |
} | |
}) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UsersChannel < ApplicationCable::Channel | |
def subscribed | |
if current_user | |
stream_for current_user | |
else | |
transmit false | |
reject | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment