使用 Rails 的 Action Cable 创建聊天

发布日期:2026-06-25 06:00:04   来源 : 杭州电子商务研究院    浏览量 :25
杭州电子商务研究院 发布日期:2026-06-25 06:00:04  
25

介绍

在本教程中,我们将探索 Ruby on Rails 的两个新功能 - Action CableActive Job。毫无疑问,Action Cable 是两者中更令人兴奋的。它集成了WebSocket通信协议,与其祖先 HTTP 相比,它提供了一些很棒的新功能,将为您提供许多构建事物的新想法。Rails 可能是第一个采用和实现 WebScoket 协议的成熟框架,因此您只能想象使用它可以构建什么的可能性!

为了最好地展示 ActionCable、WebSocket 和 Active Job 的功能,我们将使用 Ruby on Rails 5 构建一个聊天室

HTTP 和 Websockets

在 HTTP 中,服务器和客户端之间的连接寿命很短:客户端向服务器请求资源,与服务器建立连接,并将请求的资源(无论是 JSON、HTML、XML 还是某种文件)作为响应流式传输到客户端。然后,连接关闭。但客户端如何知道服务器是否有新数据或更新数据?通常,HTTP 会使用长轮询,其中客户端会“询问”服务器在给定的时间间隔内是否有新内容。

与 HTTP 不同,WebSockets 是一种协议,它使客户端和服务器能够保持开放的连接,从而使它们能够直接在彼此之间传输数据。客户端订阅服务器中的开放 websocket 连接,当有新信息时,服务器会广播数据,订阅的客户端会接收数据。这样,服务器和客户端都知道数据的状态,并且可以轻松地在发生更改时同步更改。

ActionCable 如何发挥作用?

由于 Rails 控制器是专门为处理 HTTP 请求而构建的,因此 Rails 设计了一种不同的方法来处理其与 WebSockets 的集成。Rails 5 应用程序在应用程序目录中有一个名为 channels 的新目录。Channels 通过封装有关特定单元工作(例如聊天消息或通知)的逻辑,充当 WebSocket 请求的控制器。客户端可以订阅这些通道,以便从一个或多个通道传输数据。

安装 ActionCable

Action Cable 是一项新功能,需要您拥有最新版本的 Rails 5。Rails 5 的先决条件之一是您已安装 Ruby 2.2.4(及更高版本)及其开发工具包。截至 2016 年 3 月 11 日,最新稳定版本是 Rails 5 beta3。为了获得它,您需要使用以下选项安装 rails gem:

      gem install rails --pre --no-ri --no-rdoc
    

PostgreSQL

Action Cable 需要PostgreSQL作为其适配器。您需要在操作系统上安装并配置它,然后才能继续本教程(继续,我们会等待)。

使用 pgsql 创建新的 Rails 应用程序

创建新的 Rails 应用程序时,您需要将其指定为适配器,以便新应用程序不会具有默认的 SQLite。

      rails _5.0.0.beta3_ new chatapp --database=postgresql
    

创建应用程序并配置database.yml文件以匹配您的 PostgreSQL 设置后,您就可以继续并创建一个空数据库:

      cd chatapp
rake db:create
    

奠定基础

您可能已经从新应用程序的名称中猜到了,我们将构建一个非常简单的聊天程序,利用 Action Cable 的强大功能。以下是它在几个伪代码步骤中的工作方式:

  • 创建一个名为room_channel的服务器端 websocket 通道,该通道将具有客户端订阅和取消订阅的方法,以及向客户端发送数据的方法。
  • 使用 JavaScript(本例中为 CoffeeScript)创建通道的客户端表示,称为RoomChannel(注意命名约定)。它将订阅服务器端通道,并具有在连接/断开服务器时触发的方法以及处理、发送和接收数据的方法。
  • 创建一个Rails 作业,将要创建的新消息排入数据库中,并在创建后通过 websocket 通道将其广播回来。

首先,让我们开始为聊天室搭建一个简单的控制器。它将包含聊天本身的视图。

      rails g controller rooms show
    

控制器和动作已经完成,所以让我们把它们作为应用程序的根:

      #config/routes.rb

Rails.application.routes.draw do
root to: 'rooms#show'
    

接下来,我们将创建一个模型,正如您可能猜到的那样,它被称为消息,并且它将具有一个用于存储实际消息的内容属性。

      rails g model message content:text
    

并将其迁移到数据库中。请注意,在 Rails 5 中,您可以使用rails执行 rake 任务。

      rails db:migrate
    

模型准备好后,让我们将所有消息添加到显示动作中。

      #app/controllers/rooms_controller.rb

class RoomsController < ApplicationController
  def show
    @messages = Message.all
  end
end
    

控制器和模型已经完成,是时候转到视图了。

首先,是时候删除rooms#show的脚手架视图并将其替换为:

      <h1>Chat room</h1>

<div id="messages">
  <%= render @messages %>
</div>

<form>
  <label>Say something:</label><br>
  <input type="text" data-behavior="room_speaker">
</form>
    

其次,让我们在 views 文件夹中创建一个消息文件夹,并创建用于呈现单个消息的部分:

      # app/view/messages/_message.html.erb

<div class=“message”>
  <p><%= message.content %></p>
</div>
    

render @messages将自动在views/messages目录中查找_message.html.erb部分来显示每条消息,这样我们就不必编写任何额外的东西 - 它不能比这更干燥!

另外,请确保你的applicaton.js包含 JQuery:

      // app/assets/javascripts/application.js


//= require jquery
//= require jquery_ujs
    

创建频道

到目前为止,都是标准的 Rails 内容。是时候转到有趣的部分了:创建您的第一个 ActionCable 频道。

我们需要做的第一件事是在应用程序中启用 ActionCable。只需两个简单的步骤即可完成:

  1. 将其挂载到routes.rb中。
      #config/routes.rb
     # Serve websocket cable requests in-process
   mount ActionCable.server => '/cable'
    
  1. 在cable.coffee中初始化它
      #= require action_cable
#= require_self
#= require_tree ./channels
#
@App ||= {}
App.cable = ActionCable.createConsumer()
    

您还需要检查app/views/layouts/application.html.erb的头部部分是否有<%= action_cable_meta_tag %>

Rails 引入了一个用于生成通道的新生成器,让我们运行它并看看它的作用:

      rails g channel room speak
    

运行此程序将生成两个文件;一个位于app/assets/javascripts/channels/room.coffee 的javascript 文件和一个位于app/channels/room_channel.rb的 ruby​​ 文件。

我们先来分析一下ruby文件:

      #app/channels/room_channel.rb

class RoomChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak
  end
end
    

订阅方法是客户端连接到频道时调用的默认方法,通常用于“订阅”客户端以监听更改。发言操作是我们在运行生成器时创建的自定义操作。 它将用于从其客户端表示中接收数据。

      #app/assets/javascripts/channels/room.coffee

App.room = App.cable.subscriptions.create "RoomChannel",
  connected: ->
    # Called when the subscription is ready for use on the server

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    # Called when there's incoming data on the websocket for this channel

  speak: ->
    @perform 'speak'
    

在 JavaScript 文件中,客户端通过App.room = App.cable.subscriptions.create "RoomChannel"订阅服务器。有三种默认方法:connected、disconnected(您可能已经猜到了,它处理连接的状态)和 received(它将处理从服务器端接收的数据)。JavaScript文件中的talk方法将用于将数据发送到其服务器端表示。

输入App.cable将显示 ActionCable 在客户端的实际表示。App.room是我们刚刚创建的通道。通过输入App.room.speak 我们从 room.coffee 文件中调用了 talk() 函数函数随后将数据传输到room_channel中的talk方法。

<div class="rich-text-edi
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据