|
|
||
http://subtech.g.hatena.ne.jp/secondlife/20061012/1160641587 を見てちょっとやってみたら、例外のmessageがちゃんと復元されなかったので、作りかけでやめてしまった。
「インスタンス変数が復元できない」とか書いてるけど、YAML.dumpしてYAML.loadすると普通はちゃんと復元される。
メッセージの形式はメソッド呼び出しがハッシュのキーにメソッド名で値に引数をYAML.dumpしたものを"\0"終端で。gets("\0")というのはRailsChatのまね。
返値はメソッドの返値か例外が発生した場合はその例外をYAML.dumpしたものを"\0"終端で。
require 'yaml' module YAMLRPC class Server def initialize(obj, io) @obj = obj @io = io end def serve while yaml = @io.gets("\0") begin doc = YAML.load(yaml) doc.each_pair do |key, value| ret = YAML.dump(@obj.__send__(key, *value)) @io.write ret @io.write "\0" @io.flush end rescue Exception => e @io.write YAML.dump(e) @io.write "\0" @io.flush end end @io.close end def self.start_tcp_server(obj, *tcpserver_args) require 'socket' sock = TCPServer.open(*tcpserver_args) Thread.start do while true s = sock.accept Thread.start do self.new(obj, s).serve end end end sock.addr[1] end end class Client def initialize(io) @io = io end def method_missing(sym, *args) @io.write(YAML.dump({sym => args})) @io.write("\0") ret = YAML.load(@io.gets("\0")) if ret.is_a?(Exception) raise ret else return ret end end end end if __FILE__ == $0 require 'socket' port = YAMLRPC::Server.start_tcp_server({}, '127.0.0.1', 0) p [:port, port] h = YAMLRPC::Client.new(TCPSocket.open('127.0.0.1', port)) h[1] = 'one' h['two'] = 2 p h[1] p h[2] h.fetch(3) end
問題点としては
など。