I'm trying to setup a turbo stream connection with a custom action cable channel from an erb view like this:
View
<%= turbo_stream_from "image_viewer_#{@image.id}", channel: "ImageViewerChannel", data: {image_id: @image.id} %>
<%= turbo_frame_tag "connected_users" do %>
<%= render 'connected_users', count: 0 %>
<% end %>
Channel
class ImageViewerChannel < ApplicationCable::Channel
extend Turbo::Streams::Broadcasts, Turbo::Streams::StreamName
include Turbo::Streams::StreamName::ClassMethods
@@connected_users_count = 0
def subscribed
@@connected_users_count += 1
@image_id = params[:image_id]
stream_from "image_viewer_#{@image_id}"
broadcast_connected_users_count
end
.....
private
def broadcast_connected_users_count
ActionCable.server.broadcast(
"image_viewer_#{@image_id}",
Turbo::StreamsChannel.broadcast_replace_to(
"connected_users",
target: "connected_users",
partial: "images/connected_users",
locals: { count: @@connected_users_count }
)
)
end
But I can't seem to get the connection working properly, I've confirmed redis is running and the channel is accepting connections by using a stimulus controller which successfully establishes a connection using the elevant stream identifier so my assumption is that its a problem in the view. I've also confirmed the @image instance variable is being set properly from the relevant controller and it produces the following output in HTML
<turbo-cable-stream-source channel="ImageViewerChannel" data-image-id="14" signed-stream-name="ImltYWdlX3ZpZXdlcl8xNCI=--0eeda72e7a5478708717f1013f6a650e5b36c5f313a38a50a980e004a841b092"></turbo-cable-stream-source>
Any help would be appreciated :)
EDIT:
Adding more details to assist with further debugging, I've stripped everything else from show.html.erb so it just looks like this:
<%= turbo_stream_from "image_viewer_#{@image.id}", channel: "ImageViewerChannel", data: {image_id: @image.id} %>
<%= tag.div id: :connected_users do %>
<%= render "images/connected_users", count: 0 %>
<% end %>
Controller:
def show
@image = Image.find(params[:id])
end
And the full html output:
<main class="container mx-auto mt-28 px-5 flex">
<turbo-cable-stream-source channel="ImageViewerChannel" data-image-id="15" signed-stream-name="ImltYWdlX3ZpZXdlcl8xNSI=--b6210244563c1b1182cf3b15f63f8425aae5eb267eb38660507bae79fb80e1ca"></turbo-cable-stream-source>
<div id="connected_users">
<p> Medcial Image Viewer - Connected Users: 0 </p>
</div>
</main>
App logs:
Started GET "/images/15" for 127.0.0.1 at 2024-03-01 16:31:51 +0500
Processing by ImagesController#show as HTML
Parameters: {"id"=>"15"}
Image Load (0.1ms) SELECT "images".* FROM "images" WHERE "images"."id" = ? LIMIT ? [["id", 15], ["LIMIT", 1]]
↳ app/controllers/images_controller.rb:28:in `set_image'
CACHE Image Load (0.0ms) SELECT "images".* FROM "images" WHERE "images"."id" = ? LIMIT ? [["id", 15], ["LIMIT", 1]]
↳ app/controllers/images_controller.rb:22:in `show'
Rendering layout layouts/application.html.erb
Rendering images/show.html.erb within layouts/application
Rendered images/_connected_users.erb (Duration: 0.0ms | Allocations: 14)
Rendered images/show.html.erb within layouts/application (Duration: 0.3ms | Allocations: 244)
Rendered layout layouts/application.html.erb (Duration: 6.3ms | Allocations: 6107)
Completed 200 OK in 8ms (Views: 6.6ms | ActiveRecord: 0.1ms | Allocations: 7407)
Redis is running:
brew services main * ] 4:30 pm
Name Status User File
postgresql@14 error 256 xyz ~/Library/LaunchAgents/[email protected]
redis started xyz ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
A few things that jump out: you've set up your own turbo stream channel but still sending updates through
Turbo::StreamsChannel. You're not subscribed toconnected_usersto receive any updates.broadcast_replace_towill replace your turbo frame, which means you won't have a target after the first update. You don't need a turbo frame for turbo streams to work.I think you could also just inherit from
Turbo::StreamsChannel:Update
This is what I get:
and cable message: