В Rails7 не приходят данные по WebSocket от сервера к клиенту через ActionCable из фоновой задачи
В проекте используется devise, redis и sidekiq. Я хочу запускать фоновую задачу, по завершению которой отправить клиенту сигнал на обновление страницы. В консоли браузера отображается только лог об успешном соединении. В консоли браузера лог о получение данных не появляется, значит данные не приходят. В браузере, вр вкладке разработчика, в разделе сетей вижу, что подключение по сокету есть и постоянный ping проходит, но там данные тоже не отображаются.
Почему не приходят данные и в чем может быть ошибка?
Connection
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if verified_user = env['warden'].user
verified_user
else
reject_unauthorized_connection
end
end
end
end
Канал на сервере
class BuildingConstructionChannel < ApplicationCable::Channel
def subscribed
Rails.logger.debug("Subscribing to BuildingConstructionChannel for user #{current_user.id}")
stream_for current_user
end
def unsubscribed
Rails.logger.debug("Unsubscribed from BuildingConstructionChannel for user #{current_user.id}")
end
end
Подписка к каналу на клиенте
import consumer from "channels/consumer"
consumer.subscriptions.create("BuildingConstructionChannel", {
connected() {
// Called when the subscription is ready for use on the server
console.log('Connected to BuildingConstructionChannel');
},
disconnected() {
// Called when the subscription has been terminated by the server
console.log('Disconnected from BuildingConstructionChannel');
},
received(data) {
// Called when there's incoming data on the websocket for this channel
console.log('Received data:', data);
// window.location.reload();
}
});
Контроллер где запускается фоновая задача
class BuildingsController < ApplicationController
def build
@building.update(is_under_construction: true, build_time: @building.time_requirement)
BuildingConstructionJob.perform_async(@building.id, current_user.id)
redirect_to castle_path(@building.castle), notice: 'Construction of the building has begun'
end
# остальной код
end
Фоновая задача
class BuildingConstructionJob
include Sidekiq::Worker
def perform(building_id, user_id)
begin
user = User.find(user_id)
building = Building.find(building_id)
until building.build_time.zero?
building.build_time -= 10
building.save
sleep(10)
end
building.update(is_under_construction: false, build_time: 0)
BuildingConstructionChannel.broadcast_to(user, { message: 'Building construction completed' })
rescue StandardError => e
Rails.logger.error("Error in BuildingConstructionJob: #{e.message}")
end
end
end
По логам /log/development.log видно, что соединение устанавливается, пользователь валидируется, контролер функцию выполняет, фоновую задачу запускает, данные по сокету отправялет:
Started GET "/cable" for ::1 at 2023-12-14 08:36:28 +0000
Started GET "/cable" [WebSocket] for ::1 at 2023-12-14 08:36:28 +0000
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 6], ["LIMIT", 1]]
↳ app/channels/application_cable/connection.rb:12:in `find_verified_user'
Registered connection (Z2lkOi8vZmNzL1VzZXIvNg)
Subscribing to BuildingConstructionChannel for user 6
BuildingConstructionChannel is transmitting the subscription confirmation
BuildingConstructionChannel is streaming from building_construction:Z2lkOi8vZmNzL1VzZXIvNg
... тут другие логи выполнения контролера и фоновой задачи
[ActionCable] Broadcasting to building_construction:Z2lkOi8vZmNzL1VzZXIvNg: {:message=>"Building construction completed"}
Логи sidekiq так же не показывают ошибок, видно, что запускается и успешно завершается:
2023-12-14T08:36:17.104Z pid=92135 tid=1lmj class=BuildingConstructionJob jid=07b8000b35785ffb1bbfac00 INFO: start
2023-12-14T08:37:17.343Z pid=92135 tid=1lmj class=BuildingConstructionJob jid=07b8000b35785ffb1bbfac00 elapsed=60.239 INFO: done