Server-push connections with only Rails and Mongrel

เนื่องจาก Controller ของ rails มันมี timeout

มีอีกทางเลือกหนึ่งคือ ใช้ Mongrel HttpHandler ( Suggest โดยคุณ adam )


require 'active_record'

class StatusHandler < Mongrel::HttpHandler
   def process(request, response)
      id = request.params['PATH_INFO'].slice(1, 20)
      current = request.params['QUERY_STRING']

      while status(id) == current do // ถ้าค่าเหมือนเดิมก็ hold connection ไปเรื่อยๆ
         sleep 0.2

      response.start(200) do |head, out| // ถ้าค่าไม่เหมือนเดิม complete ไป
         head["Content-Type"] = "text/html"
         out.write status(id)

   # http://localhost:3000/status/1
   # auction id = 1
   # return status

   # http://localhost:3000/status/1?100
   # เปิด connection ค้างไว้และรอจนกว่าค่าจะเปลี่ยน
   # (จะมี database queries ใน development.log แต่ไม่มี web hits )
   # ลองเปิด sql shell แล้วสั่ง “update auctions set status=101″ หลังจากนั้น connection will resolve immediately
, printing out the new value.
   def status(id)
      connection.select_value("select status from auctions where id=#{id.to_i}")
      # สมมติว่า มีตาราง auctions( status:integer ) อยู่แล้วนะ

   def connection

uri "/status", :handler =>, :in_front => true

เรายังสามารถเขียน ajax ให้เรียก


ได้ ตามนี้

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
   <%= javascript_include_tag :defaults %>
   Status is now: <span id="status"></span>

   <script language="javascript">
      function respawn()
         new Ajax.Updater('status', '/status/1?' + $('status').textContent, { onComplete: respawn }); // พอ complete แล้ว ให้เปิด connection ไปที่ server ใหม่แล้วรอค่าเปลี่ยนอีกครั้ง


เรียกได้ว่าเป็น comet แบบแปลกๆ แทนที่จะไป handle timeout ที่ client กลับไปทำให้ server ไม่มี timeout ซะงั้น

แล้ววิธีที่ส่ง request เป็น long polling ไม่ใช่ comet นะผมว่า

นอกจากนี้ rails ยังมีทางเลือกอื่นๆ ( ที่น่าจะดีกว่า ) โดยมี plugin ที่น่าสนใจ คือ

orbited (python), shooting_star(Ruby), Juggernaut (flash-base)

ref :


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s