3

我正在用 Juggernaut 2 编写一个用于实时推送通知的 Rails 应用程序,但不知道如何解决这个问题。我在聊天室中有许多用户,我想运行一个计时器,以便每 30 秒推送一次到聊天室中的每个浏览器。Juggernaut 2 是基于 node.js 构建的,所以我假设我需要在那里编写这段代码。我只是不知道从哪里开始将它与剑圣 2 集成。

4

3 回答 3

1

I just browsed through Juggernaut briefly so take my answer with a grain of salt...

  1. 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.
  2. 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

于 2011-03-08T17:37:14.307 回答
1

我们实施了一个测验系统,它以可变的时间间隔推出问题。我们是这样做的:

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”为测验计时运行后台进程,以便我们仍然可以处理传入的分数。

我不知道这是多么可扩展。

于 2011-07-12T01:09:34.980 回答
1

这是一个示例客户端,它在 Ruby 中每 30 秒推送一次。

使用 Redis 和 Node 安装你的 Juggernaut:安装 ruby​​ 和 ruby​​gems,然后gem install juggernaut运行

#!/usr/bin/env ruby
require "rubygems"
require "juggernaut"
while 1==1
 Juggernaut.publish("channel1","some Message")
 sleep 30
end
于 2011-05-31T22:04:53.653 回答