2013-04-17

Ruby & Websocket & websocket-js 支援與詳解

首先,此處使用em-websocket的gem來做websocket server

之後,直接看code才解釋

require 'rubygems'
require 'em-websocket'

EventMachine.set_descriptor_table_size(65535)

EventMachine.run do

  EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 843) do |ws|
    ws.onopen do |handshake| ; end
    ws.onclose do ; end
    ws.onmessage do |msg| ; end
  end

  #im root
  EventMachine.set_effective_user( "nobody" )
  #im nobody

  EventMachine::WebSocket.start(:host => '0.0.0.0', :port => 8080) do |ws|

    ws.onopen do |handshake|
      #your code
    end
    ws.onclose do
      #your code
    end
    ws.onmessage do |msg|
      #your code
    end
  end
end


首先,EventMachine.set_descriptor_table_size(65535)
這邊設定最大的設定值,不過因為Linux有設定openfile的最大數量,可使用指令`ulimit -a`來進行查詢

$ ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024  ### 這個數量
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


所以這個使用者只能最高有1024個connection,必須修改類似Linux下的limit.conf,應該在這個path下
`/etc/security/limits.conf`
然後增加類似

somebody  soft  nofile  65535
somebody  hard  nofile  65535

才可以突破1024數量的限制,所以OS必須要設定才行,EventMachine就再輔助設定一次,但其無法覆蓋OS的設定值

之後是Flash PolicyFile的問題(類似使用websocket-js來用Flash轉介使用websocket協定,讓IE和舊版本的瀏覽器只要有Flash就可以使用websocket),新版的v9+的Flash,在建立WebSocket時"一定"會先送出843 port來要求連線的授權,所以必須在843 port開一個service回應授權(em-websocket原生內定就會直接回傳,所以不用實作,要開而已),當然你可以就這樣把服務開在那邊,就不用像demo一樣必須開兩個port,只是可能client端的網管會把不常用的port進行封鎖,就會連結不到之類的(Chrome / Firefox有原生支援websocket,其實就不會用到這個port的)...且843 port因為小於1024,所以會需要root的權限,所以盡可能越乾淨越好

EventMachine.set_effective_user( "nobody" )

這行以上的為root權限(因為843 port必須為root才能開啓),而此行以下的為設定的使用者,一些比較複雜且dirty的code就可以放在這邊之後,相對的比較安定就是,且port與843分離,實際的流量也會準確些就是了

okay以上大概是這樣,解決幾個最大的問題
1.最大的連線數,突破1024的限制
2.Flash授權書的問題
3.執行使用者的問題(root => nobody)

沒有留言:

張貼留言