Ruby On Rails 7 ActionCable 的使用
环境
-
Rails: 7.0.3
-
Ruby: 3.1.1
一、新建一个 Rails 应用
$ rails new demo --api
二、安装 ActionCable
说是安装,实际上只要把 ActionCable 的 Engine 挂载在路由上即可。当然也可以独立运行一个 ActionCable 的服务,这里就不详细说了,具体参照官方文档
# config/routes.rb
Rails.application.routes.draw do
# 这里挂载 engine
mount ActionCable.server => '/cable'
end
三、配置 config/cable.rb 文件
ActionCable 在 development 环境下默认使用 async
adapter 。这个要求 ActionCable 推送消息时必须和 ActionCable 的服务端在同一个进程里,但是这样就没法在 Rails 自带的 console 里边调试了,所以这里我们把它改成 redis
adapter。
# config/cable.yml
development:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
test:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: demo_production
四、Redis 配置
因为上面把 ActionCable 的 adapter 设置成了 redis
,所以相应的要求我们的应用要能够连接 Redis 。这里假设我们已经安装好了 Redis。它运行在本地的 6379 端口上,并且我们已经在 Gemfile 里边启用了连接 Redis 的 gem 。
五、创建一个 Channel
这里举例创建一个新闻(news)的 channel
rails g channel news
上述命令会生成一个文件: app/channels/news_channel.rb
我们打开这个文件,设置一下 channel 的名称
# app/channels/news_channel.rb
class NewsChannel < ApplicationCable::Channel
def subscribed
# stream_from "some_channel"
stream_from "news_channel" # <- 这一行是新加的
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
六、启动服务
如果上面的步骤没有出现问题,那么 ActionCable 的服务就已经配置好了,剩下的只需启动 rails 的服务即可
$ rails s
七、在谷歌浏览器使用 javascript 连接 ActionCable
这里我们尝试在浏览器中使用 javascript 自带的 sdk 连接 ActionCable 的服务。使用 F12 打开 Chrome 控制台,贴上如下代码
let websocket = new WebSocket('ws://localhost:3000/cable')
// 注意!这里的 channel 使用的是 Channel 的类名,不是之前定义的 channel 名称
let identifier = JSON.stringify({ channel: "NewsChannel" })
let data = JSON.stringify({ command: "subscribe", identifier})
// 这里在 open 的时候订阅 channel
websocket.onopen = function(){
websocket.send(data)
}
// 这里可以定义一些 websocket 连接关闭的操作
websocket.onclose = function(){
console.log("disconnected!")
}
// 这里是定义接收到推送的消息时所做的处理
websocket.onmessage = function(e){
console.log(e.data)
}
顺利的话你会看到如下信息
八、测试推送消息
保持浏览器的页面不要刷新,不然就要重新连接 websocket 了。打开 Rails 自带的 console :
$ rails console
输入如下命令
# 这里的 channel 参数用的就是我们之前定义好的 channel 名称
ActionCable.server.broadcast("news_channel", {title: "hello world"}.to_json)
一般来说输入完会是这样的
这时再回到浏览器页面,就会看到有这样的一条消息
这就说明你成功了!
评论