如何使用ActionController :: Live以及Resque + Redis(用于聊天应用程序)
我正在尝试为我的rails应用程序构建聊天function。 我正在使用ActionController::Live
, Puma
, Resque
, Redis
。 所以基本上在这种情况下,redis subscribe
方法使用resque
在后台运行。 到目前为止,我所做的是每当用户在下面的表单字段即聊天框中输入文本时
..请求来到ChatBoxController中的Publish
方法。
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
function添加到后台作业? 或者我如何进行此实施? 需要帮助这个设计。
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
我想在Users/show
页面中显示Server Sent Events(SSE)
以及ActionController::Live
以获取通知
预REQS:
- Ruby 2.0.0+
- Rails 4.0.0+
- Redis的
- 美洲狮
初始化:
在config/initializers
目录中创建一个redis.rb
初始化文件, redis.rb
化一个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
和sub
添加两个方法。 pub
的作用是将聊天事件和消息发布到redis
,以及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
在您的routes
,将pub设为POST
并进行GET
,并将路径与/chat/publish
和/chat/subscribe
匹配。
Coffeescript / 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
。 使用EventSource ,打开SSE的通道,以便您可以接收事件,并使用该数据更新视图。 在此示例中,我们只将它们记录到javascript控制台。
代码看起来应该是这样的:
$(document).ready -> source = new EventSource('/chat/subscribe') source.addEventListener 'chat_event', (e) -> console.log(e.data)
注意: 将上面的两个代码块放在controllername.coffee
文件中,对于此示例,它应该是 app/assets/javascript
目录中的chat.js.coffee
。 您还需要确保它正在资产管道中加载。 在你的application.js
文件中require
它(如果你还没有调用require tree .
)。
启用并行请求:
在开发环境中,您必须通过将以下两行添加到config/environments/development.rb
来启用并行请求:
config.preload_frameworks = true config.allow_concurrency = true
现在启动浏览器,浏览/chat
并查看魔法。 键入消息并单击按钮时,该网页的所有实例都将收到该消息。
这就是你使用ActionController::Live
和Redis
在rails
创建基本聊天应用程序的方法。 根据您的要求,最终的代码显然会有很大不同,但这应该可以帮助您入门。
您应该查看更多资源:
- 温柔的爱情 - 它是否活着?
- Railscasts - #401 - ActionController :: Live
- SitePoint - 使用Rails和SSE进行迷你聊天
- Github - mohanraj-ramanujam / live-stream
- Thoughtbot - 使用SSE的聊天示例