Redis 未连接到 channel.js
Redis not connecting to channel.js
我还没有在网上的任何地方看到这个问题的解决方案,所以这里是。我正在使用 ActionCable 设置简单的通知。当我通过控制台或我的应用程序发送广播时,ActionCable 成功并且没有错误。
ActionCable.server.broadcast("notifications_channel_1", { notification: "Testing" })
[ActionCable] Broadcasting to notifications_channel_1: {:notification=>"Testing"}
=> 0
我也可以在我的 redis 服务器上看到它
1605237545.900905 [1 127.0.0.1:52106] "publish" "notifications_channel_1" "{"notification":"Testing"}"
问题是我的 channel.js 中没有收到任何数据,它目前只是写入控制台以进行故障排除。
通知_channel.js
import consumer from "./consumer"
consumer.subscriptions.create("NotificationsChannel", {
connected() {
console.log("connected to the server!")
},
disconnected() {
console.log("disconnected from the server")
},
received(data) {
console.log("Receiving:");
console.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
create_notification application_controller.rb
中的函数
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
notification.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
notifications/_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 %>
申请.html.erb
<%= render 'notifications/alerts' %>
我看到有人说这是一个 rails 5 的问题,用 rails 6 解决了,但我是 运行 rails 6 并且仍然有这个问题问题。
rails --version
Rails 6.0.3.4
有解决办法吗?如何让漂亮的“接收:[数据]”显示在我的控制台中?
问题源于您订阅的方式 NotificationsChannel
您没有传递用户 ID,所以您只是订阅了“NotificationsChannel”
如果您将广播替换为
ActionCable.server.broadcast("notifications_channel", { notification: "Testing" })
你的流
class NotificationsChannel < ApplicationCable::Channel
def subscribed
stream_from "notifications_channel"
end
end
然后客户端订阅中的接收回调将起作用,但由于您想要的是向特定用户发送通知,因此有多种方法可以完成此操作
- 使用
stream_for
并直接流式传输到模型,这对您来说超级简单
- 订阅您正在创建的确切频道。
如果您选择加入选项一,那么您只需将 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);
},
});
我还没有在网上的任何地方看到这个问题的解决方案,所以这里是。我正在使用 ActionCable 设置简单的通知。当我通过控制台或我的应用程序发送广播时,ActionCable 成功并且没有错误。
ActionCable.server.broadcast("notifications_channel_1", { notification: "Testing" })
[ActionCable] Broadcasting to notifications_channel_1: {:notification=>"Testing"} => 0
我也可以在我的 redis 服务器上看到它
1605237545.900905 [1 127.0.0.1:52106] "publish" "notifications_channel_1" "{"notification":"Testing"}"
问题是我的 channel.js 中没有收到任何数据,它目前只是写入控制台以进行故障排除。
通知_channel.js
import consumer from "./consumer" consumer.subscriptions.create("NotificationsChannel", { connected() { console.log("connected to the server!") }, disconnected() { console.log("disconnected from the server") }, received(data) { console.log("Receiving:"); console.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
create_notification application_controller.rb
中的函数 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
notification.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
notifications/_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 %>
申请.html.erb
<%= render 'notifications/alerts' %>
我看到有人说这是一个 rails 5 的问题,用 rails 6 解决了,但我是 运行 rails 6 并且仍然有这个问题问题。
rails --version
Rails 6.0.3.4
有解决办法吗?如何让漂亮的“接收:[数据]”显示在我的控制台中?
问题源于您订阅的方式 NotificationsChannel
您没有传递用户 ID,所以您只是订阅了“NotificationsChannel”
如果您将广播替换为
ActionCable.server.broadcast("notifications_channel", { notification: "Testing" })
你的流
class NotificationsChannel < ApplicationCable::Channel
def subscribed
stream_from "notifications_channel"
end
end
然后客户端订阅中的接收回调将起作用,但由于您想要的是向特定用户发送通知,因此有多种方法可以完成此操作
- 使用
stream_for
并直接流式传输到模型,这对您来说超级简单 - 订阅您正在创建的确切频道。
如果您选择加入选项一,那么您只需将 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);
},
});