hmmm...大概是專案到後面需要...做分散式處理…因為client的預計的量會破5000以上,只用一台伺服器似乎有點找死…所以打算弄成兩層broadcast的方式,也就是Main (N)=> Slave(1024+),這樣就可以有N * 1024+的漂亮數字出來,而前面想辦法用一層的proxy過來即可,類似nginx proxy之類的
然而看了一下Ruby的Socket的Doc…非常難用,自己管起來根本就是想不開的狀態
後來認真的玩了一下EventMachine,包括server和client的部分,以下直接的code demo
server.rb
require 'eventmachine'
require 'pp'
puts 'init server'
Thread.new do
##your code like
while true do
puts "broadcast_to_client"
EchoServer.broadcast(["Ser1" , "Ser2" , "Ser3"])
sleep(3)
end
end
class EchoServer < EventMachine::Connection
@@clients = {}
##onopen
def post_init
@@clients[self.signature] = self
puts "Add Client : #{self.signature}"
end
##onmessage(msg)
def receive_data(msg)
pp get_obj(msg)
#send_obj(["TEST1" , "TEST2" , "TEST3"])
#...do something
#close_connection
end
##onclose
def unbind
@@clients.delete(self.signature)
puts "Remove Client : #{self.signature}"
end
## object <=> string
def get_obj(msg)
return Marshal.load(msg)
end
def send_obj(obj)
return send_data(Marshal.dump(obj))
end
##broadcast to client
def self.broadcast(obj)
@@clients.each_value do |client|
client.send_obj(obj)
end
end
end
EventMachine.run do
EventMachine.start_server 'localhost' , 2000 , EchoServer
end
client.rb
require 'eventmachine'
require 'pp'
$echo_client = nil
puts 'init client'
Thread.new do
##your code like
while true do
puts "send_to_server"
if $echo_client
$echo_client.send_obj(["TEST1" , "TEST2" , "TEST3"])
end
sleep(3)
end
end
class EchoClient < EventMachine::Connection
##onopen
def post_init
$echo_client = self
end
##onmessage(msg)
def receive_data(msg)
pp get_obj(msg)
#send_obj(["TEST1" , "TEST2" , "TEST3"])
#...do something
end
##onclose
def unbind
reconnect 'localhost' , 2000
post_init
end
## client addon
def get_obj(msg)
return Marshal.load(msg)
end
def send_obj(obj)
return send_data(Marshal.dump(obj))
end
end
EventMachine::run do
EventMachine::connect('localhost' , 2000 , EchoClient)
end
okay,run server first & multi client is okay
ccc~ 這邊大概demo了一下一般EventMachine的用法,也就是如果你的程式有主流程或是其他控制,而非call-effect的方式,就要另外開Thread來作控制,而Ruby的變數都有做lock,所以就算底層是multi-thread,不過一般用起來應該都是thread safe就是了,而這邊的用法P2P也是ok的就是,你高興也可以開兩個Thread,每個Process都有EM的Client & Server,這就是P2P狀態了
而 Marshal.load(Marshal.dump()) #=> Ruby way deep clone
其實Marshal.dump就是Object.to_s,然後Marshal.load就是String.to_object,就是這簡單的意涵就是,不過傳的物件client和server都要require到,不然會無法重現回來就是…
yoo…分散式完成…不用搞難搞的Socket,可喜可賀可喜可賀X"D
沒有留言:
張貼留言