如何使用ActionController :: Live以及Resque + Redis(用于聊天应用程序)

我正在尝试为我的rails应用程序构建聊天function。 我正在使用ActionController::LivePumaResqueRedis 。 所以基本上在这种情况下,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::Livefunction添加到后台作业? 或者我如何进行此实施? 需要帮助这个设计。

 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 

控制器:

您需要向ChatControllerpubsub添加两个方法。 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::LiveRedisrails创建基本聊天应用程序的方法。 根据您的要求,最终的代码显然会有很大不同,但这应该可以帮助您入门。

您应该查看更多资源:

  • 温柔的爱情 - 它是否活着?
  • Railscasts - #401 - ActionController :: Live
  • SitePoint - 使用Rails和SSE进行迷你聊天
  • Github - mohanraj-ramanujam / live-stream
  • Thoughtbot - 使用SSE的聊天示例