[英]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::Live
, Puma
, Resque
, Redis
。 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
以获取通知
Create a redis.rb
initializer file in the config/initializers
directory, globalizing an instance of redis
. 在config/initializers
目录中创建redis.rb
初始化程序文件, redis.rb
化redis
实例。 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
You need to add two methods to your ChatController
, pub
and sub
. 您需要向ChatController
, pub
和sub
添加两个方法。 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
,使酒馆 POST
和SUB一个GET
和路径匹配像/chat/publish
和/chat/subscribe
。
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 .
)。
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::Live
和Redis
在rails
创建基本聊天应用程序的方法。 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.