“未找到订阅类”具有动作效果和铁路6 API

发布于 2025-02-13 17:19:28 字数 3312 浏览 1 评论 0原文

我使用Ruby 3.0.2p107Rails 6.1.6,并且我是Rails Backend(API)和React TypeScript前端。

后端代码

# app/channels/notification_channel.rb
class NotificationChannel < ApplicationCable::Channel
  def subscribed
    stream_from "notification_channel_#{current_user.user_id}"
  end

  def unsubscribed; end
end
# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_user
    end

    private 

    # search the current user
    def find_user
      current_user = Profile::Account.find_by(user_id: request.query_parameters[:user_id])
      current_user ? current_user : reject_unauthorized_connection
    end
  end
end

前端代码

    const createSubscription = (consumer: ActionCable.Cable) => {
        consumer.subscriptions.create({ channel: `notification_channel_${user.sub}` }, {
            connected: () => console.log(`connected to notifications.${user.sub}`),
            received: (notification) => handleReceivedNotification(notification),
        });
    };

    const handleReceivedNotification = (notification: any) => {
        console.log(JSON.stringify(notification));
    }

    useEffect((): void => {
        if (user) setComsumer(ActionCable.createConsumer(`ws://localhost:3100/cable?user_id=${user.sub}`));
    }, [user]);

    useEffect((): void => {
        if (consumer) createSubscription(consumer);
    }, [consumer]);

当我运行应用程序(后端和前端)时,我会得到连接,但找不到订阅类。

Registered connection (Z2lkOi8vYXBpL1Byb2ZpbGU6OkFjY291bnQvMQ)
Subscription class not found: "notification_channel_facebook|10157537128720479"

另外,如果我尝试从命令行进行广播,它将无法解决(返回0)。

$ ActionCable.server.broadcast "notification_channel_#{user.user_id}", { action: "new_notification" }
D, [2022-07-07T14:44:03.820530 #19220] DEBUG -- : [ActionCable] Broadcasting to notification_channel_facebook|10157537128720479: {:action=>"new_notification"}
=> 0

我还检查了redis通道,但找不到notification_channel

Redis.new.pubsub("channels")
=> ["action_cable/Z2lkOi8vYXBpL1Byb2ZpbGU6OkFjY291bnQvMQ", "_action_cable_internal"]

这是我的config/cable.yml config file

default: &default
  adapter: redis
  url: redis://localhost:6379/1

development:
  <<: *default

test:
  <<: *default

production:
  adapter: redis
  url: <%= ENV['REDIS_URL'] %>
  channel_prefix: api_production

在这里config> config/application.rb


require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
# require "sprockets/railtie"
require "rails/test_unit/railtie"
# activate the action mailer system
require "active_storage/engine"
require "action_mailbox/engine"

我相信我已经浏览了有关该主题的所有文档,但是我开始放松选择。任何帮助都将不胜感激。

谢谢

I use ruby 3.0.2p107, Rails 6.1.6 and I've a Rails backend (API) and a React Typescript frontend.

Backend code

# app/channels/notification_channel.rb
class NotificationChannel < ApplicationCable::Channel
  def subscribed
    stream_from "notification_channel_#{current_user.user_id}"
  end

  def unsubscribed; end
end
# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_user
    end

    private 

    # search the current user
    def find_user
      current_user = Profile::Account.find_by(user_id: request.query_parameters[:user_id])
      current_user ? current_user : reject_unauthorized_connection
    end
  end
end

Frontend code

    const createSubscription = (consumer: ActionCable.Cable) => {
        consumer.subscriptions.create({ channel: `notification_channel_${user.sub}` }, {
            connected: () => console.log(`connected to notifications.${user.sub}`),
            received: (notification) => handleReceivedNotification(notification),
        });
    };

    const handleReceivedNotification = (notification: any) => {
        console.log(JSON.stringify(notification));
    }

    useEffect((): void => {
        if (user) setComsumer(ActionCable.createConsumer(`ws://localhost:3100/cable?user_id=${user.sub}`));
    }, [user]);

    useEffect((): void => {
        if (consumer) createSubscription(consumer);
    }, [consumer]);

When I run the app (backend and frontend) I get the connection but can't find the subscription class.

Registered connection (Z2lkOi8vYXBpL1Byb2ZpbGU6OkFjY291bnQvMQ)
Subscription class not found: "notification_channel_facebook|10157537128720479"

Also if I try a broadcast from command line, it does not work out (returns 0).

$ ActionCable.server.broadcast "notification_channel_#{user.user_id}", { action: "new_notification" }
D, [2022-07-07T14:44:03.820530 #19220] DEBUG -- : [ActionCable] Broadcasting to notification_channel_facebook|10157537128720479: {:action=>"new_notification"}
=> 0

I checked also the Redis channels but I can't find the notification_channel.

Redis.new.pubsub("channels")
=> ["action_cable/Z2lkOi8vYXBpL1Byb2ZpbGU6OkFjY291bnQvMQ", "_action_cable_internal"]

Here my config/cable.yml config file

default: &default
  adapter: redis
  url: redis://localhost:6379/1

development:
  <<: *default

test:
  <<: *default

production:
  adapter: redis
  url: <%= ENV['REDIS_URL'] %>
  channel_prefix: api_production

Here the imports of config/application.rb


require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
# require "sprockets/railtie"
require "rails/test_unit/railtie"
# activate the action mailer system
require "active_storage/engine"
require "action_mailbox/engine"

I believe I've been through all the documentation I could find about the topic, but I'm starting loose on options. Any help would be really appreciated.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

匿名。 2025-02-20 17:19:28

看起来我一直在找到答案,这

要 感谢本文 API和客户端要使用的操作电缆不在导轨上,转到config/application.rb,包括:

config.action_cable.disable_request_forgery_protection = true
config.action_cable.url = "/cable"

我也意识到,确定的用户只需要在连接阶段使用,而对于订阅,我需要使用模块名称。

consumer.subscriptions.create({ channel: `NotificationChannel` }, {
  received: (notification) => handleReceivedNotification(notification),
});

现在,如果我播放一条消息,它可以顺利进行

ActionCable.server.broadcast "notification_channel_#{user.user_id}", { action: "new_notification" }

Looks like I've been finding an answer thanks to this article

As the action cable to be used by API and client is not on rails, go to config/application.rb and include:

config.action_cable.disable_request_forgery_protection = true
config.action_cable.url = "/cable"

Also I realized that the user identified needs to be used only in the connection phase, while for the subscription I need to use the module name.

consumer.subscriptions.create({ channel: `NotificationChannel` }, {
  received: (notification) => handleReceivedNotification(notification),
});

Now if I broadcast a message, it works smoothly

ActionCable.server.broadcast "notification_channel_#{user.user_id}", { action: "new_notification" }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文