Reputation: 397
I'm testing ActionCable with a very simple example. I want to see how many users are connected at a time on a website. Users are not registered in the system. Users are assigned a session variable with a uuid. To make the example as simple as possible I have not included a model or database.
#app/controller/users_controller.rb
class UsersController < ApplicationController
def index
if session[:user].nil?
session[:user] = SecureRandom.uuid
end
@user = session[:user]
UserBroadcastJob.perform_later @user
end
end
Views are very simple
#app/views/users/index.html.erb
<h1>Users</h1>
<div id="users">
<%= render "user",user: @user %>
</div>
Partial for users:
#app/views/users/_user.html.erb
<div class="user">
User : <%= user %>
</div>
I use a job to call socket
#app/jobs/user_broadcast_job.rb
class UserBroadcastJob < ApplicationJob
queue_as :default
def perform(user)
ActionCable.server.broadcast 'user_channel', message: render_user(user)
end
def render_user(user)
ApplicationController.renderer.render(partial: 'users/user', locals: { user: user })
end
end
And the channel
App.user = App.cable.subscriptions.create "UserChannel",
connected: ->
disconnected: ->
received: (data) ->
console.log(data)
$("#users").prepend(data.message)
This works correctly. In each browser I open the uuid are connected is visible. As I do not use database for persistence, the first open browser has all the uuid and the rest of the browsers goes n-1 uuid visible. It's not important.
My question is:
If a browser closes, how can I send a message to delete the uuid from the template?
ActionCable does not work with sessions.
Ruby version: 2.4.0 Rails version: 5.1.3 jquery installed via yarn
Thanks!!!!
Upvotes: 2
Views: 3144
Reputation: 577
It will very helpful for you
class AppearanceChannel < ApplicationCable::Channel
def subscribed
stream_from "appearance"
@current_user = User.find(params[:room])
@current_user.appear
ActionCable.server.broadcast('appearance',{data: @current_user.appear,action: 'SubscribedList'})
end
def unsubscribed
if @current_user.present?
ActionCable.server.broadcast('appearance',{data: @current_user.disappear,action: 'SubscribedList'})
end
end
end
You can pass param to subscribe but impossible params with unsubscribe. so store current_user to one variable when you call subscribe and said to for destroy me at unsubscribe side.
Upvotes: 2
Reputation: 1279
You can do this under
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
in your channels/application_cable/your_channel.rb
Besides, ActionCable does work with sessions, it takes a bit of tweaking though.
If you're serious about testing the concurrency of ActionCable (i.e have serious thoughts about using ActionCable in an upscale production), I would kind of advise you to give up already and plugin anyCable. Will save you a ton of time.
Upvotes: 0