如何将 ActionController::Live 与 Resque + Redis 一起使用(用于聊天应用程序)

2024-04-28

我正在尝试为我的 Rails 应用程序构建聊天功能。我在用ActionController::Live, Puma, Resque, Redis为了这。所以基本上在这种情况下,redissubscribe方法正在后台运行,使用resque。 到目前为止,我所做的是每当用户在下面的表单字段(即聊天框)中输入文本时

    <%= form_tag chat_box_publish_path, method: :get do %>
        <%= text_field_tag :query, params[:query], class: "form-control", id: "chatSearchBox",
            placeholder: 'Search' %>
    <% end %>

..请求即将到来Publish中的方法ChatBoxController.

def publish
    $redis.publish("chat_message:1:1", "#{params[:query]}")
    respond_to do |format|
        format.js {render nothing: true}
    end
end

..现在我有以下背景Resque使用以下代码运行作业以进行测试。因此,每当发布聊天消息时,它都会打印data这很好。但我怎样才能添加ActionController::Live后台作业的功能?或者我该如何实施?需要有关此设计的帮助。

class ChatBoxInitiator
    @queue = :chat_box_initiator

    private
    def self.perform
    $redis.subscribe('chat_message:1:1') do |on|
            on.message do |event, data|
                puts "====#{data}"
                return data
            end
        end
    end
end

我想展示Server Sent Events(SSE)随着ActionController::Live用于通知Users/show page


先决条件:

  • 红宝石 2.0.0+
  • 导轨 4.0.0+
  • Redis
  • Puma

初始化器:

创建一个redis.rb初始化程序文件在config/initializers目录,全球化实例redis。建立一个heartbeat线程(5 秒到 5 分钟之间的任何时间都可以,具体取决于您的要求):

$redis = Redis.new

heartbeat_thread = Thread.new do
  while true
    $redis.publish("heartbeat","thump")
    sleep 15.seconds
  end
end

at_exit do
  heartbeat_thread.kill
  $redis.quit
end

控制器:

您需要将两个方法添加到您的ChatController, pub and sub。的作用pub是将聊天事件和消息发布到redis, and sub订阅这些事件。它应该看起来像这样:

class ChatController < ApplicationController
    include ActionController::Live

    skip_before_filter  :verify_authenticity_token

    def index
    end

    def pub
        $redis.publish 'chat_event', params[:chat_data].to_json
        render json: {}, status: 200
    end

    def sub
        response.headers["Content-Type"] = "text/event-stream"

        redis = Redis.new
        redis.subscribe(['chat_event', 'heartbeat']) do |on|
            on.message do |event, data|
                response.stream.write "event: #{event}\ndata: #{data}\n\n"
            end
        end
    rescue IOError
        logger.info "Stream Closed"
    ensure
        redis.quit
        response.stream.close
    end
end

In your routes, make pub a POST and sub a GET,并将路径与类似的东西相匹配/chat/publish and /chat/subscribe.


咖啡脚本/Javascript:

假设您的聊天应用程序的实际网页位于/chat,你需要写一些JavaScript实际发送和接收聊天消息。

为了便于理解,我们假设您的网页只有一个文本框和一个按钮。点击按钮应该将文本框的内容发布到聊天流,我们可以使用 AJAX 来做到这一点:

$('button#send').click (e) ->
    e.preventDefault()
    $.ajax '/chat/publish',
        type: 'POST'
        data:
            chat_data: {
                message: $("input#message").val()
                timestamp: $.now()
        error: (jqXHR, textStatus, errorThrown) ->
            console.log "Failed: " + textStatus 
        success: (data, textStatus, jqXHR) ->
            console.log "Success: " + textStatus

现在,您还需要能够订阅和接收聊天消息。你需要使用EventSource为了这。使用事件源,为 SSE 打开一个通道,以便您可以接收事件,并使用该数据来更新视图。在此示例中,我们仅将它们记录到 javascript 控制台。

代码应该如下所示:

$(document).ready ->
    source = new EventSource('/chat/subscribe')
    source.addEventListener 'chat_event', (e) ->
        console.log(e.data)

Note: 将上面的两个代码块放在您的controllername.coffee文件,对于本例来说应该是chat.js.coffee在你的app/assets/javascript目录。您还需要确保它已加载到资产管道中。require它在你的application.js文件(如果您还没有调用require tree .).


启用并行请求:

在您的开发环境中,您必须通过将这两行添加到您的config/environments/development.rb:

config.preload_frameworks = true
config.allow_concurrency = true

现在启动浏览器,浏览到/chat并见证魔法。当您键入消息并单击按钮时,该网页的所有实例都会收到该消息。


这就是你如何制作一个基本的聊天应用程序rails using ActionController::Live and Redis。根据您的要求,最终的代码显然会非常不同,但这应该可以帮助您入门。

您应该查看更多资源:

  • 温柔的做爱 -是直播吗? http://tenderlovemaking.com/2012/07/30/is-it-live.html
  • 铁路广播 -#401 - ActionController::Live http://railscasts.com/episodes/401-actioncontroller-live
  • 站点点 -与 Rails 和 SSE 的迷你聊天 http://www.sitepoint.com/mini-chat-rails-server-sent-events/
  • GitHub -mohanraj-ramanujam / 直播 https://github.com/mohanraj-ramanujam/live-stream
  • 思想机器人 -使用 SSE 的聊天示例 https://robots.thoughtbot.com/chat-example-app-using-server-sent-events
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 ActionController::Live 与 Resque + Redis 一起使用(用于聊天应用程序) 的相关文章

  • ruby 中的数组切片返回不同的结果 - nil 与空数组

    我对以下事实感到困惑 如果对数组进行切片length 它返回一个空数组 但长度大于该值时 它返回nil 这是什么原因呢 例如 arr 1 2 3 4 5 这样做 在哪里y gt arr length and x是任意正整数 返回nil ar
  • 如何按值降序对哈希进行排序并在 ruby​​ 中输出哈希?

    output sort by k v v reverse 和钥匙 h a gt 1 c gt 3 b gt 2 d gt 4 gt a gt 1 c gt 3 b gt 2 d gt 4 Hash h sort 现在我有这两个 但我试图按值
  • Rails 3 沙箱控制台

    在 Rails 2 中你可以运行 script console sandbox 这样您就可以使用生产数据而不会意外破坏任何东西 我似乎找不到 Rails 3 的等效命令 有人知道它是什么吗 很简单 输入 bundle exec rails
  • 如何将命令行参数传递给 rake 任务

    我有一个 rake 任务需要将一个值插入到多个数据库中 我想从命令行或从another耙任务 我怎样才能做到这一点 您可以通过向任务调用添加符号参数来指定 rake 中的形式参数 例如 require rake task my task a
  • 使用 Ruby 验证 Jenkins 插件表单

    我正在用 Ruby 开发一个 Jenkins 插件 您应该能够配置连接到服务器的每个节点 以便在该节点失去与主服务器的连接时将电子邮件发送到指定的地址 EmailNodeProperty添加一个字段来输入电子邮件地址 Save an ema
  • 如何在 Ruby 中使用循环输出所有可能的组合?

    我刚刚开始学习编程 并试图编写一个输出所有可能组合的函数 到目前为止 我已经能够找到尺寸 2 的所有可能组合 但我不确定如何使代码保持开放式以处理更大尺寸的组合 某种递归会有用吗 我知道我可以使用内置的组合方法 但我只是想弄清楚如何从头开始
  • 使用 RSpec 请求规范授权请求时,access_token 无效

    我正在尝试测试CredentialsController 使用 RSpec 请求规范在生产中运行良好 Code 控制器 class CredentialsController lt ApplicationController before
  • 如何将openId与rails 3中的设备集成

    我是 Rails 新手 刚刚完成了一个简单的设计设置 我正在寻求实现一些仍然使用核心设计功能集但允许通过 openid 提供商登录而不是 使用电子邮件或用户名注册 的东西 我如何开始使用最新的设计宝石和rails 3 看看devise op
  • 执行 rvm use 2.0.0 --default 时收到“警告!路径未正确设置”

    以上第一次不起作用 第二次起作用 尝试将任何新 shell 窗口的 ruby 版本设置为 2 0 0 Doing rvm use 2 0 0 default gives Warning PATH is not properly set up
  • 使用 prawnto_2 gem 加载图像时,RAILS_ROOT 不再有效

    我正在将我的应用程序从 Rails 3 0 升级到 Rails 3 1 我已经尽可能地将旧插件转为 gems 其中包括用这个漂亮闪亮的新插件替换旧的 prawnto 插件对虾 2 https github com forrest prawn
  • 如何使用回形针对多页 pdf 进行缩略图

    我想让 Paperclip 为上传的多页 PDF 文件的每一页创建 2 个缩略图 我正在运行 Paperclip 2 3 1 1 并在我的资产模型中使用它 has attached file asset styles gt medium g
  • 新手:我的例子中的文本替换

    In my 红宝石 on Rails应用程序中 我的助手中有一个方法 它通过以下方式打开文件 content File open myfile txt The 文件内容就好像 my car my seat my age my son my
  • Rails 4 - 将地址保存为数据库中的一列

    我是 Rails 新手 正在开发一个简单的应用程序 我的 ERD 中有一个名为 Client 的模型 并且希望保存每个客户的地址 我最初的想法是将地址保存为单独的字段 即 rails g model Client address first
  • cron 爬虫使用 Ruby 中的 Google API 将数据插入 Google 电子表格的授权问题

    我的项目是每天早上 9 00 抓取某些网络数据并将它们放入我的 Google 电子表格中 并且它必须获得读取和写入某些内容的授权 这就是为什么下面的代码位于顶部 Google API CLIENT ID blah blah CLIENT S
  • Rails 日志太详细

    如何防止 Rails 记录过多日志 这是我的 production log 文件中的典型跟踪 许多部分 缓存命中 它在开发中很有用 但我不希望在我的生产环境中使用它 Started GET redirected true for 46 19
  • Ruby on Rails:simple_form + Twitter Bootstrap 未显示

    我正在为我的网站上的新用户创建一个简单的注册表单 我已经运行了 simple form bootstrap 的安装 rails g simple form install bootstrap 但是 它仍然没有显示并呈现为正常的 simple
  • 使用pluginaweek的state_machine,我可以在事件期间引用activerecord对象吗?

    我正在尝试实现一个 挂起 事件 将对象转换为 挂起状态 但我需要能够 取消暂停 并返回到之前的状态 我向模型添加了 previous state 字段 但我看不到如何在事件块内访问它 这是我试图实现的基本逻辑 event suspend d
  • 如何在 RoR 中实施成就系统

    我正在尝试在我的 Ruby on Rails 应用程序中实现一个成就系统 但效果很差 我有一长串想要检查的成就 所有这些都是由各种控制器中的某些创建操作触发的 我的想法是我将拥有一个成就模型 其中包括控制器及其响应的操作 然后对创建进行之前
  • 删除嵌套属性不起作用

    我似乎无法使用删除项目accepts nested attributes for命令 但我已经按照本教程 http railscasts com episodes 196 nested model form revised以及相关的git
  • Ruby 单引号和双引号

    我最近一直在使用 Ruby 进行编码 并且之前使用过 Python 据我所知 单引号和双引号对代码的工作方式没有影响 我转向 Ruby 是为了了解它是如何工作的 并研究 Ruby 和 Python 之间的相似之处 我曾经使用过单引号字符串并

随机推荐

  • 在 Selenium Node JS 中打开 gecko 驱动程序的日志记录

    我目前正在使用Selenium 与 Node Js and FireFox并想打开日志记录功能壁虎司机 但我不确定如何 另外我还想知道在哪里可以找到日志 目前这是我实例化驱动程序的方式 var fOptions new firefox Op
  • .net 日历 - 使整个单元执行回发(可点击)

    我已经启动并运行了一个 net 日历 并从数据库中获取信息 默认情况下 天数会应用回发操作 我想做的是将该操作应用于整个单元格 这样用户就不需要仅单击文本链接 我是 dayRenderer 操作 我有以下行来尝试复制该操作 但第二个参数我不
  • 如何强制操作系统收回内存? (C++)

    在我的 C 代码中 我分配了大量内存来创建树 然后在每个节点中使用 删除 来释放内存 删除所有内容后 我检查操作系统使用的内存量 发现内存未释放 这是预期的 因为该进程不会立即将内存返回给操作系统 因为它仍然可能会再次使用它 问题是 我在删
  • 您可以通过 facebook graph api 来控制和定位页面帖子吗?

    Enabling post privacy gating in the Page s privacy settings allows creating of posts with separate Gating and Targeting
  • 不同程序集中的实体容器和模型生成

    我正在做一些重构 并尝试重用我生成的实体模型 我的应用程序有一些程序集 其中一个是我的外向公共类型 API 另一个包含提供程序的实现 例如日志 我想拆分实体和模型的生成 以便实体位于 API 程序集中 容器位于实现程序集中 这可能吗 有可能
  • 将base64转换为base62(不含特殊字符)

    我想在 URL 中传递河豚加密字符串 并希望像 base64 一样对其进行编码 但没有任何特殊字符 像 base62 这样的东西就很好 0 9a zA Z 所以我想做的是使用base64 encode 转换河豚加密字符串 并将base64
  • 如何使用不同的类和导入动态地使用 Python 日志记录来更改文件句柄

    我无法执行即时日志文件句柄更改 例如 我有3节课 one py import logging class One def init self txt logging debug Hey I m the class One and I say
  • WP7 上的 POST 请求

    我花了大约 6 个小时试图弄清楚如何在 WP7 中发出常规 POST 请求 我尝试了此处和许多其他地方发布的类似问题的答案 我还尝试了许多不同的 API POST 请求 它们都导致针对某一特定问题 远程服务器返回错误 NotFound 好像
  • 通过 CloudFlare 获取正确的访客 IP [重复]

    这个问题在这里已经有答案了 我正在使用其他人转售给我的 cPanel 这可能意味着我无法使用mod cloudflare 我想获取访问者的 IP 而不是 CloudFlare IP 我正在使用的代码部分 SERVER REMOTE ADDR
  • 让子进程等待直到收到父进程的信号

    我想从父级创建 N 个子级 我希望所有的孩子同时开始 一个功能 测量时间 因此 我将该函数放入信号处理程序中 当父级完成创建 分叉 所有子级时 它会向所有子级发送信号 使用kill children id 以让 make 开始 代码如下 但
  • 将多个子域映射到同一个 S3 存储桶

    有没有某种方法可以将多个 数千个 子域映射到一个 s3 存储桶 如果是这样 是否也可以将其映射到每个子域的存储桶中的特定路径 我希望 test1 example com 映射到 mybucket test1 test2 example co
  • 如何批量删除Redis中数十万个带有特殊字符的key

    我们有一个包含数十万个 Redis 键的列表 其中包含各种特殊字符 我们希望批量删除它们 对于这个问题上的类似问题 有一些很好的答案 如何使用 Redis 自动删除与模式匹配的键 https stackoverflow com questi
  • 将 JSON 与嵌套数组和 json 进行比较(数组顺序无关紧要)

    你好 我正在尝试比较java中的两个json 每个键可以包含一个json对象或json对象数组 并且它们中的每个也可以是数组或json 这是 Json 的示例 id 123123asd123 attributes name apps val
  • 为什么在生产中得到空 CSS 文件?

    我在文件中放入了很多css文件active admin css scss Active Admin s got SASS import active admin mixins import active admin base import
  • TypeScript:使用调用签名和构造函数签名实现接口

    是否可以创建一个实现以下接口的对象 interface I string new any 我看到可以实现一个具有调用签名和这个问题的一些字段的接口 使用裸函数签名和其他字段实现 TypeScript 接口 https stackoverfl
  • 动态添加组件到 JDialog

    当用户单击 JDialog 上的按钮时 我在将组件添加到 JDialog 时遇到问题 基本上我希望它看起来像这样 然后 当用户单击 添加新字段 时 我希望它看起来像这样 我似乎无法打开添加新 JLabel 或 JTextField 的对话框
  • Javascript 子字符串方法帮助

    长话短说 我正在开发一个 Web 应用程序并在其中使用 AJAX 我试图禁用点击时链接的默认操作 将哈希值附加到链接 然后从网址中删除 我遇到的问题是 虽然哈希值被相应地附加 但子字符串方法并没有提取 而是提取了它后面的字母 这是我的代码
  • 在 WKWebView 中加载本地文件在设备中不起作用

    我无法在 wkwebview 中加载本地 epub 文件 从文档目录 它可以在模拟器中运行 但不能在设备中运行 我了解到这是 iOS 8 的一个错误here http www openradar me 18039024 iOS 8 已经解决
  • MaxLength 数据注释是否可以与 List 一起使用?

    一个可以用 MaxLength 具有字符串和简单数组的属性 i e MaxLength 500 public string ProductName get set Or MaxLength 50 public string Products
  • 如何将 ActionController::Live 与 Resque + Redis 一起使用(用于聊天应用程序)

    我正在尝试为我的 Rails 应用程序构建聊天功能 我在用ActionController Live Puma Resque Redis为了这 所以基本上在这种情况下 redissubscribe方法正在后台运行 使用resque 到目前为