From ae7cf7c37d6bb78eddb0d36b60d94436124460aa Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sun, 15 Mar 2009 14:52:06 -0700 Subject: [PATCH] Add ObjectProtocol --- lib/em/protocols.rb | 2 ++ lib/em/protocols/object_protocol.rb | 39 +++++++++++++++++++++++++++++ tests/test_object_protocol.rb | 37 +++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 lib/em/protocols/object_protocol.rb create mode 100644 tests/test_object_protocol.rb diff --git a/lib/em/protocols.rb b/lib/em/protocols.rb index 21ccfc35d..9f2d673de 100644 --- a/lib/em/protocols.rb +++ b/lib/em/protocols.rb @@ -8,6 +8,7 @@ module EventMachine # - LineAndTextProtocol and LineText2 # - HeaderAndContentProtocol # - Postgres3 + # - ObjectProtocol # # The protocol implementations live in separate files in the protocols/ subdirectory, # but are auto-loaded when they are first referenced in your application. @@ -29,5 +30,6 @@ module Protocols autoload :SASLauth, 'em/protocols/saslauth' autoload :Memcache, 'em/protocols/memcache' autoload :Postgres3, 'em/protocols/postgres3' + autoload :ObjectProtocol, 'em/protocols/object_protocol' end end diff --git a/lib/em/protocols/object_protocol.rb b/lib/em/protocols/object_protocol.rb new file mode 100644 index 000000000..deec6cb7d --- /dev/null +++ b/lib/em/protocols/object_protocol.rb @@ -0,0 +1,39 @@ +module EventMachine + module Protocols + # ObjectProtocol allows for easy communication using marshaled ruby objects + # + # module RubyServer + # include EM::P::ObjectProtocol + # + # def receive_object obj + # send_object({'you said' => obj}) + # end + # end + # + module ObjectProtocol + def receive_data data # :nodoc: + (@buf ||= '') << data + + while @buf.size >= 4 + if @buf.size >= 4+(size=@buf.unpack('N').first) + @buf.slice!(0,4) + receive_object Marshal.load(@buf.slice!(0,size)) + else + break + end + end + end + + # Invoked with ruby objects received over the network + def receive_object obj + # stub + end + + # Sends a ruby object over the network + def send_object obj + data = Marshal.dump(obj) + send_data [data.respond_to?(:bytesize) ? data.bytesize : data.size, data].pack('Na*') + end + end + end +end diff --git a/tests/test_object_protocol.rb b/tests/test_object_protocol.rb new file mode 100644 index 000000000..0ab320476 --- /dev/null +++ b/tests/test_object_protocol.rb @@ -0,0 +1,37 @@ +$:.unshift "../lib" +require 'eventmachine' +require 'test/unit' + +class TestObjectProtocol < Test::Unit::TestCase + Host = "127.0.0.1" + Port = 9550 + + module Server + include EM::P::ObjectProtocol + def post_init + send_object :hello=>'world' + end + def receive_object obj + $server = obj + EM.stop + end + end + + module Client + include EM::P::ObjectProtocol + def receive_object obj + $client = obj + send_object 'you_said'=>obj + end + end + + def test_send_receive + EM.run{ + EM.start_server Host, Port, Server + EM.connect Host, Port, Client + } + + assert($client == {:hello=>'world'}) + assert($server == {'you_said'=>{:hello=>'world'}}) + end +end \ No newline at end of file