I am writing a rails app with Juggernaut 2 for real-time push notifications and am not sure how to approach this problem. I have a number of users in a chat room and I would like to run a timer so that a push can go out to each browser in the chat room every 30 seconds. Juggernaut 2 is built on node.js, so I'm assuming I need to write this code there. I just have no idea where to start in terms of integrating this with Juggernaut 2.
-
2Doesn't https://github.com/maccman/juggernaut explain where to start? – Dmytrii Nagirniak Mar 08 '11 at 02:26
-
Yea, Juggernaut is working and I have a chat app, I am just trying to add a server side timer in node.js and integrate it with Juggernaut. – TenJack Mar 09 '11 at 09:40
3 Answers
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

- 8,440
- 5
- 49
- 69

- 7,581
- 4
- 28
- 40
-
Still trying to figure this all out. This is a great lead, thanks a lot. – TenJack Mar 09 '11 at 06:09
-
-
Hi ambertech, the main thing I am struggling with right now is that I would like to initiate a timer for a specific channel name, not for all channels. I need to be able to start a timer for each individual chat room. Thanks for any help. – TenJack Mar 14 '11 at 00:51
Here is a sample client which pushes every 30 seconds in Ruby.
Install your Juggernaut with Redis and Node: install ruby and rubygems, then run gem install juggernaut
and
#!/usr/bin/env ruby
require "rubygems"
require "juggernaut"
while 1==1
Juggernaut.publish("channel1","some Message")
sleep 30
end

- 104,111
- 38
- 209
- 254

- 11
- 1
We implemented a quiz system which pushed out questions on a variable time interval. We did it as follows:
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
The key in our case was using 'spawn' to run a background process for the quiz timing so that we could still process the incoming scores.
I have no idea how scalable this is.

- 1,801
- 3
- 22
- 33