我正在用 Juggernaut 2 编写一个用于实时推送通知的 Rails 应用程序,但不知道如何解决这个问题。我在聊天室中有许多用户,我想运行一个计时器,以便每 30 秒推送一次到聊天室中的每个浏览器。Juggernaut 2 是基于 node.js 构建的,所以我假设我需要在那里编写这段代码。我只是不知道从哪里开始将它与剑圣 2 集成。
3 回答
I just browsed through Juggernaut briefly so take my answer with a grain of salt...
- You might be interested in the Channel object (https://github.com/maccman/juggernaut/blob/master/lib/juggernaut/channel.js) You'll notice that Channel.channel is an object (think ruby's hash) of all the channels that exist. You can set a 30 second recurring timer (setInterval - http://nodejs.org/docs/v0.4.2/api/timers.html#setInterval) to do something with all your channels.
What to do in each loop iteration? Well, the link to the aforementioned Channel code has a publish method:
publish: function(message){ var channels = message.getChannels(); delete message.channels; for(var i=0, len = channels.length; i < len; i++) { message.channel = channels[i]; var clients = this.find(channels[i]).clients; for(var x=0, len2 = clients.length; x < len2; x++) { clients[x].write(message); } }
}
So you basically have to create a Message object with message.channels set to Channel.channels and if you pass that message to the publish method, it will send out to all your clients.
As to the contents of your message, I dunno what you are using client side (socket.io? a chat client someone already built for you off Juggernaut and socket.io?) so that's up to you.
As for where to put the code creating the interval and firing off the callback to publish your message to all channels, you might want to check here in the code that creates the actual server listening on the given port: (https://github.com/maccman/juggernaut/blob/master/lib/juggernaut/server.js) If you attach the interval within init(), then as soon as you start the server it will be checking every 30 seconds to publish your given message to every channel
我们实施了一个测验系统,它以可变的时间间隔推出问题。我们是这样做的:
def start_quiz
Rails.logger.info("*** Quiz starting at #{Time.now}")
$redis.flushall # Clear all scores from database
quiz = Quiz.find(params[:quizz] || 1 )
@quiz_master = quiz.user
quiz_questions = quiz.quiz_questions.order("question_no ASC")
spawn_block do
quiz_questions.each { |q|
Rails.logger.info("*** Publishing question #{q.question_no}.")
time_alloc = q.question_time
Juggernaut.publish( select_channel("/quiz_stream"), {:q_num => q.num, :q_txt => q.text :time=> time_alloc} )
sleep(time_alloc)
scoreboard = publish_scoreboard
Juggernaut.publish( select_channel("/scoreboard"), {:scoreboard => scoreboard} )
}
end
respond_to do |format|
format.all { render :nothing => true, :status => 200 }
end
end
在我们的案例中,关键是使用“spawn”为测验计时运行后台进程,以便我们仍然可以处理传入的分数。
我不知道这是多么可扩展。
这是一个示例客户端,它在 Ruby 中每 30 秒推送一次。
使用 Redis 和 Node 安装你的 Juggernaut:安装 ruby 和 rubygems,然后gem install juggernaut
运行
#!/usr/bin/env ruby
require "rubygems"
require "juggernaut"
while 1==1
Juggernaut.publish("channel1","some Message")
sleep 30
end