📅  最后修改于: 2023-12-03 14:59:10.980000             🧑  作者: Mango
Action Cable 是 Rails 中的一项功能,它使得 WebSocket 通讯变得简单。而 Nuxt.js 则是 Vue 的一种服务端渲染框架。如何将二者结合起来,实现一个实时通讯的网站呢?
首先,在 Ruby on Rails 项目中安装 Action Cable。打开项目的 Gemfile,在其中加入:
gem 'actioncable'
然后,在项目根目录下运行 bundle
命令,安装依赖包。
Action Cable 不会自动加入 Rails 项目。让我们手动运行安装命令:
rails action_cable:install
这将会创建 app/channels
,以及修改 config/routes.rb
。在 routes.rb
中已经帮我们创建了一个 mount
语句,将 Action Cable 挂在到指定的路由上。
Action Cable 还需要 redis 来作为消息队列,因此我们还需要安装并启动 redis 服务。
在 Action Cable 中,Channel 用来组织 WebSocket 的消息,并将其传递给订阅的客户端。一个 Channel 负责一类消息,而可以有多个客户端订阅它。
首先,让我们为 User 创建一个 Channel。在 app/channels
目录下,创建名为 user_channel.rb
的文件,内容如下:
class UserChannel < ApplicationCable::Channel
def subscribed
stream_for current_user
end
end
上述代码中,UserChannel
继承自 ApplicationCable::Channel
。在 subscribed
方法中,我们定义了订阅行为。调用 stream_for
方法将 current_user 订阅到 User 的 Channel 上。
现在,我们已经为 User 创建了一个 Channel。下面,我们来测试一下:
rails console
UserChannel.broadcast_to(User.first, { message: "Hello, user!" })
你应该可以在控制台看到消息传递的结果了。
接下来,我们需要在 Nuxt.js 中编写 WebSocket 相关的代码。在实际应用中,建议把这些代码放到 Vuex 中,以便管理。我们在这里为了演示,将代码放在了页面的 mounted
钩子中。
在页面中,首先定义并初始化 WebSocket:
const WebSocket = require('websocket').w3cwebsocket
export default {
...
data() {
return {
socket: null
}
},
mounted() {
this.socket = new WebSocket("ws://localhost:3000/cable")
this.socket.onmessage = (message) => {
const data = JSON.parse(message.data)
console.log('Received message:', data)
}
}
...
}
WebSocket 的查询参数和 Rails 的 session 类似,需要传递一个 token
参数。其值可以是 cookie 等客户端唯一标识。例如,我们可以在 Nuxt.js 中将 token
保存在 Vuex 的 state 中,并在 WebSocket 初始化时将其传递。
当 WebSocket 接收到消息时,我们将消息解析为 JSON,然后打印到控制台。
最后,让我们测试一下:
rails console
UserChannel.broadcast_to(User.first, { message: "Hello, user!" })
你应该可以在控制台看到 Nuxt.js 中接收到消息的结果了。
通过使用 Action Cable,我们可以轻松地在 Rails 中建立一个实时通讯的系统。而 Nuxt.js 则可以使得我们的页面服务端渲染,为我们带来更好的 SEO。将它们结合起来,我们可以创建一个功能强大的实时应用。
在实际使用中,我们可能还需要在 Channel 中处理订阅、取消订阅等事件,以及在 Nuxt.js 中建立一个心跳机制等等。不过,对于一个基本的实时通讯应用来说,以上的代码已经足够了。