【问题标题】:Redis not connecting to channel.jsRedis 没有连接到 channel.js
【发布时间】:2021-02-25 20:14:36
【问题描述】:

我还没有在网上看到任何解决方案,所以就这样吧。我正在使用 ActionCable 设置简单的通知。当我通过控制台或我的应用程序发送广播时,ActionCable 成功并且没有错误。

    ActionCable.server.broadcast("notifications_channel_1", { notification: "Testing" })

[ActionCable] 广播到 notifications_channel_1:{:notification=>"Testing"} => 0

我也可以在我的 redis 服务器上看到它

1605237545.900905 [1 127.0.0.1:52106] "publish" "notifications_channel_1" "{"notification":"Testing"}"

问题是我在我的 channel.js 中没有收到任何数据,它目前只是写入控制台以进行故障排除。

notifications_channel.js

从“./consumer”导入消费者 consumer.subscriptions.create("NotificationsChannel", { 连接的() { console.log("已连接到服务器!") }, 断开连接(){ console.log("与服务器断开连接") }, 收到(数据){ console.log("接收:"); 控制台.log(data.content); } } );

在浏览器中,我可以看到我的“已连接到服务器!”出现,所以我知道我已连接,但按下我设置的测试按钮不会产生“接收:[数据]”。以下是我的应用程序中所有相关的代码部分:

config/initializers/redis.rb

    redis_host = Rails.application.secrets.redis && Rails.application.secrets.redis['host'] || 'localhost'
    redis_port = Rails.application.secrets.redis && Rails.application.secrets.redis['port'] || 6379
    
    # The constant below will represent ONE connection, present globally in models, controllers, views etc for the instance. No need to do Redis.new everytime
    REDIS = Redis.new(host: redis_host, port: redis_port.to_i)

environments/development.rb

      Rails.root.join('config/cable.yml')
      config.action_cable.url = "ws://localhost:3000/cable"

cable.yml

    development:
      adapter: redis
      url: redis://127.0.0.1:6379/1

index.html.erb

    <%= link_to "Test Notifications", test_path, method: :post %>

notification_test 控制器操作

      def notification_test
        @project = Project.first
        create_notification(current_user, @project, "teammate",
                            "#{@project.name}: Added to the team! Check out your new dashboard by visiting the project!")
      end

application_controller.rb 中的create_notification 函数

      def create_notification(user, project, link, body)
        notification = Notification.new(user_id: user.id, project_id: project.id, 
                                        link: link, body: body)
        notification.save
      end

通知.rb

  after_create_commit { NotificationBroadcastJob.perform_later self }

notification_broadcast_job.rb

    class NotificationBroadcastJob < ApplicationJob
      queue_as :default
    
      def perform(notification)
        ActionCable.server.broadcast("notifications_channel_#{notification.user_id}", { 
        notification: render_notification(notification) })
      end
    
      private
    
      def render_notification(notification)
        ApplicationController.renderer.render(partial: 'notifications/alerts', locals: { notification: notification })
      end
    end

notifications_channel.rb

    class NotificationsChannel < ApplicationCable::Channel
      def subscribed
        stream_from "notifications_#{current_user.id}"
    
      end
    
      def unsubscribed
        stop_all_streams
      end
    end

通知/_alerts.html.erb

    <% if defined?(notification) %>>
      <div class="uk-container">
        <div uk-alert="animation">
          <a class="uk-alert-close" uk-close></a>
          <%= notification.body %>
        </div>
      </div>
    <% end %>

application.html.erb

    <%= render 'notifications/alerts' %>

我看到有人说这是 Rails 5 的问题,已经用 rails 6 解决了,但我正在运行 rails 6 并且仍然遇到这个问题。

    rails --version

导轨 6.0.3.4

有解决办法吗?如何让漂亮的“接收:[数据]”显示在我的控制台中?

【问题讨论】:

  • 看起来您正在订阅NotificationsChannel,但正在向NotificactionsChannel#{some_id}广播
  • @RolandStuder 我的订阅函数中的'stream_from "notifications_#{current_user.id}"' 没有让我订阅 NotificationsChannel?当我启动我的服务器时,我得到这个:[ActionCable] [1] NotificationsChannel 正在传输订阅确认 [ActionCable] [1] NotificationsChannel 正在从 notifications_1 流式传输

标签: ruby-on-rails ruby redis actioncable


【解决方案1】:

问题源于您订阅 NotificationsChannel 的方式,您没有传递用户 ID,因此您只是订阅“NotificationsChannel”

如果您将广播替换为

ActionCable.server.broadcast("notifications_channel", { notification: "Testing" })

还有你的流

class NotificationsChannel < ApplicationCable::Channel
  def subscribed
    stream_from "notifications_channel"
  end
end

然后,您的客户端订阅中的接收回调将起作用,但由于您想要向特定用户发送通知,因此有多种方法可以完成此操作

  1. 使用 stream_for 并直接流式传输到模型,这对您来说非常容易
  2. 订阅您正在创建的确切频道。

如果您选择选项一,那么您只需将 stream_from 替换为 stream_for

class NotificationsChannel < ApplicationCable::Channel
  def subscribed
    stream_for current_user
  end
end

此处无需更改,保持您的客户端代码不变。

如果您选择加入选项二,则使用流式传输

class NotificationsChannel < ApplicationCable::Channel
  def subscribed
    stream_from "notifications_#{params[:user_id]}"
  end
end

你的客户应该像这样创建一个订阅

consumer.subscriptions.create({channel: "NotificationsChannel", user_id: 1}), {
  connected() {
    console.log("connected to the server!");
  },

  disconnected() {
    console.log("disconnected from the server");
  },

  received(data) {
    console.log("Receiving:");
    console.log(data.content);
  },
});

【讨论】:

猜你喜欢
  • 2020-06-29
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
相关资源
最近更新 更多