Francis, Thanks, this works quite nicely. With a nice recursive setup I''m able to send out the information I need. Here''s my solution, it''s not clean but it definitely works: class ProtoCamera < EventMachine::Connection def receive_data(data) puts "Got data! #{data}" @image_count ||= 0 send_image end def send_image if @image_count < 100 EM.next_tick { image_name = "images/image-#{@image_count}.jpg" length = File.size(image_name) puts "Sending image #{@image_count}: #{length}" File.open(image_name, "rb") do |file| send_data "Content-length: #{length}\n" send_data "\n" send_data file.read send_data "\n" end @image_count += 1 send_image } # Try to keep around 8 frames a second sleep(1.0 / 8.0) end end end EventMachine::run { EventMachine::start_server "localhost", 8080, ProtoCamera } Is there a proper way to sleep on this? I have a feeling that pausing direct execution may not be the best way, but as this is a simple example it doesn''t seem that harmful. Jason On 10/9/07, Francis Cianfrocca <garbagecat10 at gmail.com> wrote:> > #send_data buffers outbound data in userland, as you surmised, and doesn''t > actually write the network until the next "turn" through the reactor loop. > > So you need to cause the reactor to turn at some point in your processing. > > > The easiest way is probably to use EM#next_tick (documented in the rdoc), > or a Spawned Process (documented in the file SPAWNED_PROCESSES). > > #next_tick was originally designed for throttling the output to remote > network peers, but your requirement fits well enough. > > send_data data > EM.next_tick { send_more_data } > > and then return from your function. The block passed to #next_tick will be > executed AFTER a pass through the reactor core, which will dispatch the data > that has already been passed to send_data. > > Make sense? Let me know if it works. > > Also, we should cross post this to the EM ML so that others can benefit. > > On 10/9/07, Jason Roelofs < jameskilton at gmail.com> wrote: > > > > Francis, > > > > I''m writing a small server to push "streaming" image data and I''m kind > > of stuck. I can''t seem to find a way to force-flush the data I''ve written to > > the socket, so it all gets sent after receive_data is done, which doesn''t > > work for me. > > > > It''s a pseudo MotionJPEG server, looks like this: > > > > class ProtoCamera < EventMachine::Connection > > > > def receive_data(data) > > puts "Got data! #{data}" > > send_images > > end > > > > def send_images > > @image_count ||= 0 > > > > while @image_count < 50 > > image_name = "images/image-#{@image_count}.jpg" > > length = File.size(image_name) > > puts "Sending image #{@image_count}: #{length}" > > > > # Try to keep around 8 frames a second > > sleep(1.0 / 8.0) > > > > File.open(image_name, "rb") do |file| > > send_data "Content-length: #{length}\n" > > send_data "\n" > > send_data file.read > > send_data "\n" > > > > --- NEED TO FLUSH HERE ---- > > end > > > > @image_count += 1 > > end > > end > > end > > > > As it stands, all 50 pieces of image data don''t get sent until the end. > > How do I force a socket flush whenever I want? > > > > Thanks > > > > Jason > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/eventmachine-talk/attachments/20071009/d5ec7ff7/attachment.html