简体   繁体   English

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

[英]How to use ActionController::Live along with Resque + Redis (for Chat application)

I am trying to build a chat feature for my rails application. 我正在尝试为我的rails应用程序构建聊天功能。 I am using ActionController::Live , Puma , Resque , Redis for this. 我正在使用ActionController::LivePumaResqueRedis So basically in this case, redis subscribe method is running in background using resque . 所以基本上在这种情况下,redis subscribe方法使用resque在后台运行。 So far what i have done is whenever a user enters a text in below form field ie chat box 到目前为止,我所做的是每当用户在下面的表单字段即聊天框中输入文本时

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

..the request is coming to Publish method in ChatBoxController . ..the请求即将Publish在方法ChatBoxController

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

..now i have a below background Resque job running with below code for testing purposes. ..现在我有一个以下背景Resque作业运行与下面的代码用于测试目的。 So whenever a chat message is posted, its printing the data which is fine. 因此,每当发布聊天消息时,它打印的data都很好。 But how can i add ActionController::Live feature to the background job ? 但是,我如何将ActionController::Live功能添加到后台作业? or how do i go about this implementation ? 或者我如何进行此实施? Need help with this design. 需要帮助这个设计。

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

and i want to show the Server Sent Events(SSE) along with ActionController::Live for notifications in Users/show page 我想在Users/show页面中显示Server Sent Events(SSE)以及ActionController::Live以获取通知

Pre-Reqs: 预REQS:

  • Ruby 2.0.0+ Ruby 2.0.0+
  • Rails 4.0.0+ Rails 4.0.0+
  • Redis Redis的
  • Puma 美洲狮

Initializer: 初始化:

Create a redis.rb initializer file in the config/initializers directory, globalizing an instance of redis . config/initializers目录中创建redis.rb初始化程序文件, redis.rbredis实例。 It's also a good idea to set up a heartbeat thread (Anything from 5 seconds to 5 minutes is okay, depending on your requirements): 设置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

Controller: 控制器:

You need to add two methods to your ChatController , pub and sub . 您需要向ChatControllerpubsub添加两个方法。 The role of pub is to publish chat events and messages to redis , and sub to subscribe to these events. pub的作用是将聊天事件和消息发布到redis ,以及sub来订阅这些事件。 It should look something like this: 它应该看起来像这样:

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 , and match the path to something like /chat/publish and /chat/subscribe . 在你的routes ,使酒馆 POSTSUB一个GET和路径匹配像/chat/publish/chat/subscribe


Coffeescript / Javascript: Coffeescript / Javascript:

Assuming your actual webpage for the chat app is at /chat , you need to write some Javascript to actually send and receive chat messages. 假设您的聊天应用程序的实际网页位于/chat ,您需要编写一些Javascript来实际发送和接收聊天消息。

For ease of understanding, let's suppose your webpage only has a textbox and a button. 为了便于理解,我们假设您的网页只有一个文本框和一个按钮。 Hitting the button should publish the content of the textbox to the chat stream, we can do that using AJAX: 点击按钮应该将文本框的内容发布到聊天流,我们可以使用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

Now, you need to be able to subscribe and receive the chat messages as well. 现在,您还需要能够订阅和接收聊天消息。 You need to use EventSource for this. 您需要使用EventSource Using EventSource , open a channel for SSE so that you can receive events, and use that data to update the view. 使用EventSource ,打开SSE的通道,以便您可以接收事件,并使用该数据更新视图。 In this example, we will only log them to the javascript console. 在此示例中,我们只将它们记录到javascript控制台。

The code should look something like this: 代码看起来应该是这样的:

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

Note: Place both of the code blocks above in your controllername.coffee file, for this example it should be chat.js.coffee in your app/assets/javascript directory. 注意: 将上面的两个代码块放在controllername.coffee文件中,对于此示例,它应该是 app/assets/javascript目录中的chat.js.coffee You also need to make sure it's being loaded in the asset pipeline. 您还需要确保将其加载到资产管道中。 require it in your application.js file (if you aren't already calling require tree . ). 在你的application.js文件中require它(如果你还没有调用require tree . )。


Enable Parallel Requests: 启用并行请求:

In your development environment, you'll have to enable parallel requests by adding these two lines to your config/environments/development.rb : 在开发环境中,您必须通过将以下两行添加到config/environments/development.rb来启用并行请求:

config.preload_frameworks = true
config.allow_concurrency = true

Now fire up your browser, browse to /chat and see the magic. 现在启动浏览器,浏览/chat并查看魔法。 When you type a message and click the button, the message will be received by all instances of that webpage. 键入消息并单击按钮时,该网页的所有实例都将收到该消息。


Well this is how you make a basic chat application in rails using ActionController::Live and Redis . 这就是你使用ActionController::LiveRedisrails创建基本聊天应用程序的方法。 The final code would obviously be very different depending on your requirements but this should get you started. 根据您的要求,最终的代码显然会有很大不同,但这应该可以帮助您入门。

Some more resources you should check out: 您应该查看更多资源:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM