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
      end

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

   # 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 ) อยู่แล้วนะ
   end

   def connection
      ActiveRecord::Base.connection
   end
end

uri "/status", :handler => StatusHandler.new, :in_front => true

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

http://localhost:3000/status/1?100

ได้ ตามนี้

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
   <%= javascript_include_tag :defaults %>
</head>
<body>
   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 ใหม่แล้วรอค่าเปลี่ยนอีกครั้ง
      }

      respawn();
   </script>
</body>
</html>

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

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

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

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

ref :

http://adamac.blogspot.com/2007/11/comet-on-rails.html

Advertisements

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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