hessian2 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -10
  3. data/README.md +197 -197
  4. data/hessian2.gemspec +0 -2
  5. data/lib/hessian2/client.rb +57 -50
  6. data/lib/hessian2/constants.rb +164 -164
  7. data/lib/hessian2/fault.rb +3 -3
  8. data/lib/hessian2/handler.rb +18 -18
  9. data/lib/hessian2/hessian_client.rb +3 -3
  10. data/lib/hessian2/parser.rb +619 -619
  11. data/lib/hessian2/type_wrapper.rb +49 -49
  12. data/lib/hessian2/version.rb +3 -3
  13. data/lib/hessian2/writer.rb +499 -499
  14. data/lib/hessian2.rb +14 -14
  15. data/spec/binary_spec.rb +51 -51
  16. data/spec/boolean_spec.rb +26 -26
  17. data/spec/class_wrapper_spec.rb +52 -52
  18. data/spec/create_monkeys.rb +14 -14
  19. data/spec/date_spec.rb +45 -45
  20. data/spec/double_spec.rb +78 -78
  21. data/spec/int_spec.rb +54 -54
  22. data/spec/list_spec.rb +66 -66
  23. data/spec/long_spec.rb +68 -68
  24. data/spec/map_spec.rb +36 -36
  25. data/spec/null_spec.rb +17 -17
  26. data/spec/object_spec.rb +78 -78
  27. data/spec/ref_spec.rb +43 -43
  28. data/spec/spec_helper.rb +23 -23
  29. data/spec/string_spec.rb +61 -61
  30. data/spec/struct_wrapper_spec.rb +47 -47
  31. data/spec/type_wrapper_spec.rb +102 -102
  32. data/test/app.rb +24 -24
  33. data/test/async/em_http_asleep.rb +25 -25
  34. data/test/async/em_http_sleep.rb +25 -25
  35. data/test/async/monkey.asleep.rb +27 -27
  36. data/test/async/mysql2_aquery.rb +37 -37
  37. data/test/fault/monkey.undefined_method.rb +5 -5
  38. data/test/fault/monkey.wrong_arguments.rb +5 -5
  39. data/test/fiber_concurrency/em_http_asleep.rb +17 -17
  40. data/test/fiber_concurrency/em_http_sleep.rb +17 -17
  41. data/test/fiber_concurrency/monkey.asleep.fiber_aware.rb +18 -18
  42. data/test/fiber_concurrency/mysql2_query.rb +29 -29
  43. data/test/fiber_concurrency/net_http_asleep.rb +19 -19
  44. data/test/fiber_concurrency/net_http_sleep.rb +19 -19
  45. data/test/fibered_rainbows/Gemfile +15 -15
  46. data/test/fibered_rainbows/config.ru +11 -11
  47. data/test/fibered_rainbows/rainbows.rb +13 -13
  48. data/test/monkey_service.rb +16 -16
  49. data/test/prepare.rb +7 -7
  50. data/test/thread_concurrency/active_record_execute.rb +29 -29
  51. data/test/thread_concurrency/monkey.asleep.rb +22 -22
  52. data/test/thread_concurrency/net_http_asleep.rb +24 -24
  53. data/test/thread_concurrency/net_http_sleep.rb +24 -24
  54. data/test/threaded_rainbows/Gemfile +13 -13
  55. data/test/threaded_rainbows/config.ru +9 -9
  56. data/test/threaded_rainbows/rainbows.rb +13 -13
  57. metadata +4 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3e89025e74e937f051cc7c5532bd58d003dd3cc
4
- data.tar.gz: 127b7703579d72674763c1f64c6aea4ef72ef051
3
+ metadata.gz: 3b9a89d291633b69257f589b65f232b5dcc38466
4
+ data.tar.gz: 69d82afa46069344e29a162c978ec3c095b9a0de
5
5
  SHA512:
6
- metadata.gz: 229b79558ab04006522bc54ed2fb139ae305621ba0b174da4d4007fff713c74435c4864d3d33075490e28381ef209ab44fc71f70d515df1702f32bf27ce0525b
7
- data.tar.gz: b1ce0ce88dfe6696ea2a3741ebdb43bf1db8500f4f5d9f79fe602e85ee2446ad42db2c1795bd05385cfe3953069fa3b9ac985f8d694e971ebcdf4ad6a25bdc4c
6
+ metadata.gz: 336224add2f6534f56e6c1357567f6e165550c9a24f9e466b4530966c6d9a821844d1c7c8190aa69de8bffb979704e0fa791a95d61c7e9ad70cd9478f26a092e
7
+ data.tar.gz: 26a9830f996c2a9bd0a4b3e2ea342bbd9ff532c2dc2b6fee33abf9fbdca6d0c0b1151b7e114e14ef9ad545e0db3b83b75de8aef563a61e8cb029bc7e2240ce34
data/.gitignore CHANGED
@@ -1,10 +1,10 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- doc/*
5
- pkg/*
6
- spec/*.yml
7
- spec/*.jpg
8
- test/*.data
9
- test/*.txt
10
- test/*.yml
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ doc/*
5
+ pkg/*
6
+ spec/*.yml
7
+ spec/*.jpg
8
+ test/*.data
9
+ test/*.txt
10
+ test/*.yml
data/README.md CHANGED
@@ -1,197 +1,197 @@
1
- # hessian2
2
-
3
- like json, additionally, 麻绳2 parse your object as a struct.
4
-
5
- hessian2 implements hessian 2.0 protocol. look [web services protocol](http://hessian.caucho.com/doc/hessian-ws.html) and [serialization protocol](http://hessian.caucho.com/doc/hessian-serialization.html).
6
-
7
- ## comparing
8
-
9
- yajl-ruby: json, fast.
10
-
11
- msgpack: binary, faster.
12
-
13
- protobuf: encoding your object with schema.
14
-
15
- marshal: powerful, fast, but ruby only.
16
-
17
- hessian2: powerful as marshal but parse object to struct, clean api, smaller.
18
-
19
- ## install
20
-
21
- ```
22
- gem install hessian2
23
- ```
24
-
25
- ## serializing
26
-
27
- ```
28
- require 'hessian2'
29
- ```
30
-
31
- ``` ruby
32
- attributes = { born_at: Time.new(2009, 5, 8), name: '大鸡', price: 99.99 }
33
- monkey = Monkey.new(attributes)
34
- #=> #<Monkey id: nil, born_at: "2009-05-08 00:00:00", name: "\u5927\u9E21", price: #<BigDecimal:2b7c568,'0.9998999999 999999E2',27(45)>>
35
-
36
- bin = Hessian2.write(monkey)
37
- ```
38
-
39
- ## deserializing
40
-
41
- ``` ruby
42
- monkey = Hessian2.parse(bin)
43
- #=> #<struct id=nil, born_at=2009-05-08 00:00:00 +0800, name="\u5927\u9E21", price=99.99>
44
- ```
45
-
46
- ## struct wrapper
47
-
48
- for hash and object, only send values that specified.
49
-
50
- ``` ruby
51
- MonkeyStruct = Struct.new(:born_at, :name)
52
-
53
- wrapped_monkey = Hessian2::StructWrapper.new(MonkeyStruct, monkey)
54
- bin = Hessian2.write(wrapped_monkey)
55
- ```
56
-
57
- parsing values-binary to a monkey struct
58
-
59
- ``` ruby
60
- monkey = Hessian2.parse(bin, MonkeyStruct)
61
- #=> #<struct born_at=2009-05-08 00:00:00 +0800, name="\u5927\u9E21">
62
- ```
63
-
64
- monkeys
65
-
66
- ``` ruby
67
- wrapped_monkeys = Hessian2::StructWrapper.new([MonkeyStruct], monkeys)
68
- bin = Hessian2.write(wrapped_monkeys)
69
-
70
- monkeys = Hessian2.parse(bin, [MonkeyStruct])
71
- ```
72
-
73
- struct wrapper supports: hash, object, [hash, [object
74
-
75
- ## class wrapper
76
-
77
- for statically typed languages.
78
-
79
- ``` ruby
80
- wrapped_monkey = Hessian2::ClassWrapper.new('com.sun.java.Monkey', monkey)
81
- ```
82
-
83
- monkeys
84
-
85
- ``` ruby
86
- wrapped_monkeys = Hessian2::ClassWrapper.new('[com.sun.java.Monkey', monkeys)
87
- ```
88
-
89
- class wrapper supports: hash, object, [hash, [object
90
-
91
- ## type wrapper
92
-
93
- wrap a string to long
94
-
95
- ``` ruby
96
- str = '-0x8_000_000_000_000_000'
97
- heslong = Hessian2::TypeWrapper.new(:long, str)
98
- ```
99
-
100
- wrap a file to binary
101
-
102
- ``` ruby
103
- binstr = IO.binread(File.expand_path("../Lighthouse.jpg", __FILE__))
104
- hesbin = Hessian2::TypeWrapper.new(:bin, binstr)
105
- ```
106
-
107
- there are types: 'L', 'I', 'B', '[L', '[I', '[B', :long, :int, :bin, [:long], [:int], [:bin]
108
-
109
- ## :symbolize_keys parser option
110
-
111
- ``` ruby
112
- bin = Hessian2.write(attributes)
113
- hash = Hessian2.parse(bin, nil, symbolize_keys: true)
114
- #=> {:born_at=>2009-05-08 00:00:00 +0800, :name=>"\u5927\u9E21", :price=>99.99}
115
- ```
116
-
117
- ## client
118
-
119
- ``` ruby
120
- url = 'http://127.0.0.1:9292/monkey'
121
- client = Hessian2::Client.new(url)
122
- ```
123
-
124
- call remote method, send a monkey
125
-
126
- ``` ruby
127
- client.send_monkey(monkey)
128
- ```
129
-
130
- ## service
131
-
132
- extend hessian handler
133
-
134
- ``` ruby
135
- class MonkeyService
136
- extend Hessian2::Handler
137
-
138
- def self.send_monkey(monkey)
139
- # ...
140
- end
141
- ```
142
-
143
- handle request
144
-
145
- ``` ruby
146
- post '/monkey' do
147
- MonkeyService.handle(request.body.read)
148
- end
149
- ```
150
-
151
- ## fiber_aware
152
-
153
- fibered service, fiber aware client. use em-synchrony/em-http post.
154
-
155
- ``` ruby
156
- client = Hessian2::Client.new(url, fiber_aware: true)
157
- concurrency = 2
158
-
159
- EM.synchrony do
160
- EM::Synchrony::FiberIterator.new(0...10, concurrency).each do |i|
161
- puts client.asleep
162
- end
163
-
164
- EM.stop
165
- end
166
- ```
167
-
168
- ## async
169
-
170
- evented service, asynchronous callbacks. use em-synchrony/em-http apost.
171
-
172
- ``` ruby
173
- client = Hessian2::Client.new(url, async: true)
174
-
175
- EM.run do
176
- http = client.asleep
177
- http.callback do |r|
178
- puts Hessian2.parse_rpc(r.response)
179
- EM.stop
180
- end
181
-
182
- http.errback do |r|
183
- puts r.error
184
- EM.stop
185
- end
186
-
187
- puts "posted."
188
- end
189
- ```
190
-
191
- ## todo
192
-
193
- supports packet and envelope
194
-
195
- ## authors
196
-
197
- [takafan](http://hululuu.com)
1
+ # hessian2
2
+
3
+ like json, additionally, 麻绳2 parse your object as a struct.
4
+
5
+ hessian2 implements hessian 2.0 protocol. look [web services protocol](http://hessian.caucho.com/doc/hessian-ws.html) and [serialization protocol](http://hessian.caucho.com/doc/hessian-serialization.html).
6
+
7
+ ## comparing
8
+
9
+ yajl-ruby: json, fast.
10
+
11
+ msgpack: binary, faster.
12
+
13
+ protobuf: encoding your object with schema.
14
+
15
+ marshal: powerful, fast, but ruby only.
16
+
17
+ hessian2: powerful as marshal but parse object to struct, clean api, smaller.
18
+
19
+ ## install
20
+
21
+ ```
22
+ gem install hessian2
23
+ ```
24
+
25
+ ## serializing
26
+
27
+ ```
28
+ require 'hessian2'
29
+ ```
30
+
31
+ ``` ruby
32
+ attributes = { born_at: Time.new(2009, 5, 8), name: '大鸡', price: 99.99 }
33
+ monkey = Monkey.new(attributes)
34
+ #=> #<Monkey id: nil, born_at: "2009-05-08 00:00:00", name: "\u5927\u9E21", price: #<BigDecimal:2b7c568,'0.9998999999 999999E2',27(45)>>
35
+
36
+ bin = Hessian2.write(monkey)
37
+ ```
38
+
39
+ ## deserializing
40
+
41
+ ``` ruby
42
+ monkey = Hessian2.parse(bin)
43
+ #=> #<struct id=nil, born_at=2009-05-08 00:00:00 +0800, name="\u5927\u9E21", price=99.99>
44
+ ```
45
+
46
+ ## struct wrapper
47
+
48
+ for hash and object, only send values that specified.
49
+
50
+ ``` ruby
51
+ MonkeyStruct = Struct.new(:born_at, :name)
52
+
53
+ wrapped_monkey = Hessian2::StructWrapper.new(MonkeyStruct, monkey)
54
+ bin = Hessian2.write(wrapped_monkey)
55
+ ```
56
+
57
+ parsing values-binary to a monkey struct
58
+
59
+ ``` ruby
60
+ monkey = Hessian2.parse(bin, MonkeyStruct)
61
+ #=> #<struct born_at=2009-05-08 00:00:00 +0800, name="\u5927\u9E21">
62
+ ```
63
+
64
+ monkeys
65
+
66
+ ``` ruby
67
+ wrapped_monkeys = Hessian2::StructWrapper.new([MonkeyStruct], monkeys)
68
+ bin = Hessian2.write(wrapped_monkeys)
69
+
70
+ monkeys = Hessian2.parse(bin, [MonkeyStruct])
71
+ ```
72
+
73
+ struct wrapper supports: hash, object, [hash, [object
74
+
75
+ ## class wrapper
76
+
77
+ for statically typed languages.
78
+
79
+ ``` ruby
80
+ wrapped_monkey = Hessian2::ClassWrapper.new('com.sun.java.Monkey', monkey)
81
+ ```
82
+
83
+ monkeys
84
+
85
+ ``` ruby
86
+ wrapped_monkeys = Hessian2::ClassWrapper.new('[com.sun.java.Monkey', monkeys)
87
+ ```
88
+
89
+ class wrapper supports: hash, object, [hash, [object
90
+
91
+ ## type wrapper
92
+
93
+ wrap a string to long
94
+
95
+ ``` ruby
96
+ str = '-0x8_000_000_000_000_000'
97
+ heslong = Hessian2::TypeWrapper.new(:long, str)
98
+ ```
99
+
100
+ wrap a file to binary
101
+
102
+ ``` ruby
103
+ binstr = IO.binread(File.expand_path("../Lighthouse.jpg", __FILE__))
104
+ hesbin = Hessian2::TypeWrapper.new(:bin, binstr)
105
+ ```
106
+
107
+ there are types: 'L', 'I', 'B', '[L', '[I', '[B', :long, :int, :bin, [:long], [:int], [:bin]
108
+
109
+ ## :symbolize_keys parser option
110
+
111
+ ``` ruby
112
+ bin = Hessian2.write(attributes)
113
+ hash = Hessian2.parse(bin, nil, symbolize_keys: true)
114
+ #=> {:born_at=>2009-05-08 00:00:00 +0800, :name=>"\u5927\u9E21", :price=>99.99}
115
+ ```
116
+
117
+ ## client
118
+
119
+ ``` ruby
120
+ url = 'http://127.0.0.1:9292/monkey'
121
+ client = Hessian2::Client.new(url)
122
+ ```
123
+
124
+ call remote method, send a monkey
125
+
126
+ ``` ruby
127
+ client.send_monkey(monkey)
128
+ ```
129
+
130
+ ## service
131
+
132
+ extend hessian handler
133
+
134
+ ``` ruby
135
+ class MonkeyService
136
+ extend Hessian2::Handler
137
+
138
+ def self.send_monkey(monkey)
139
+ # ...
140
+ end
141
+ ```
142
+
143
+ handle request
144
+
145
+ ``` ruby
146
+ post '/monkey' do
147
+ MonkeyService.handle(request.body.read)
148
+ end
149
+ ```
150
+
151
+ ## fiber_aware
152
+
153
+ fibered service, fiber aware client. use em-synchrony/em-http post.
154
+
155
+ ``` ruby
156
+ client = Hessian2::Client.new(url, fiber_aware: true)
157
+ concurrency = 2
158
+
159
+ EM.synchrony do
160
+ EM::Synchrony::FiberIterator.new(0...10, concurrency).each do |i|
161
+ puts client.asleep
162
+ end
163
+
164
+ EM.stop
165
+ end
166
+ ```
167
+
168
+ ## async
169
+
170
+ evented service, asynchronous callbacks. use em-synchrony/em-http apost.
171
+
172
+ ``` ruby
173
+ client = Hessian2::Client.new(url, async: true)
174
+
175
+ EM.run do
176
+ http = client.asleep
177
+ http.callback do |r|
178
+ puts Hessian2.parse_rpc(r.response)
179
+ EM.stop
180
+ end
181
+
182
+ http.errback do |r|
183
+ puts r.error
184
+ EM.stop
185
+ end
186
+
187
+ puts "posted."
188
+ end
189
+ ```
190
+
191
+ ## todo
192
+
193
+ supports packet and envelope
194
+
195
+ ## authors
196
+
197
+ [takafan](http://hululuu.com)
data/hessian2.gemspec CHANGED
@@ -22,6 +22,4 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency 'rspec'
23
23
  s.add_runtime_dependency 'activerecord'
24
24
  s.add_runtime_dependency 'bigdecimal'
25
- s.add_runtime_dependency 'em-http-request'
26
- s.add_runtime_dependency 'em-synchrony'
27
25
  end
@@ -1,50 +1,57 @@
1
- require 'uri'
2
- require 'net/http'
3
- require 'em-synchrony/em-http'
4
- require 'hessian2'
5
-
6
- module Hessian2
7
- class Client
8
- attr_accessor :user, :password
9
- attr_reader :scheme, :host, :port, :path, :proxy
10
-
11
- def initialize(url, options = {})
12
- uri = URI.parse(url)
13
- @scheme, @host, @port, @path = uri.scheme, uri.host, uri.port, uri.path.empty? ? '/' : uri.path
14
- @path += "?#{uri.query}" if uri.query
15
- raise "Unsupported Hessian protocol: #{@scheme}" unless %w(http https).include?(@scheme)
16
- @async = options.delete(:async)
17
- @fiber_aware = options.delete(:fiber_aware)
18
- @proxy = options
19
- end
20
-
21
-
22
- def method_missing(id, *args)
23
- return invoke(id.id2name, args)
24
- end
25
-
26
- private
27
-
28
- def invoke(method, args)
29
- req_head = { 'Content-Type' => 'application/binary' }
30
- req_body = Hessian2.call(method, args)
31
-
32
- if @async
33
- EM::HttpRequest.new("#{@scheme}://#{@host}:#{@port}#{@path}").apost(body: req_body, head: req_head)
34
- elsif @fiber_aware
35
- http = EM::HttpRequest.new("#{@scheme}://#{@host}:#{@port}#{@path}").post(body: req_body, head: req_head)
36
- Hessian2.parse_rpc(http.response)
37
- else
38
- req = Net::HTTP::Post.new(@path, req_head)
39
- req.basic_auth @user, @password if @user
40
- conn = Net::HTTP.new(@host, @port, *@proxy.values_at(:host, :port, :user, :password))
41
- conn.use_ssl = true and conn.verify_mode = OpenSSL::SSL::VERIFY_NONE if @scheme == 'https'
42
- conn.start do |http|
43
- res = http.request(req, req_body)
44
- Hessian2.parse_rpc(res.body)
45
- end
46
- end
47
- end
48
-
49
- end
50
- end
1
+ require 'uri'
2
+ require 'hessian2'
3
+
4
+ module Hessian2
5
+ class Client
6
+ attr_accessor :user, :password
7
+ attr_reader :scheme, :host, :port, :path, :proxy
8
+
9
+ def initialize(url, options = {})
10
+ uri = URI.parse(url)
11
+ @scheme, @host, @port, @path = uri.scheme, uri.host, uri.port, uri.path.empty? ? '/' : uri.path
12
+ @path += "?#{uri.query}" if uri.query
13
+ raise "Unsupported Hessian protocol: #{@scheme}" unless %w(http https).include?(@scheme)
14
+ @async = options.delete(:async)
15
+ @fiber_aware = options.delete(:fiber_aware)
16
+ if @async || @fiber_aware
17
+ begin
18
+ require 'em-synchrony/em-http'
19
+ rescue LoadError => error
20
+ raise "Missing EM-Synchrony dependency: gem install em-synchrony em-http-request"
21
+ end
22
+ else
23
+ require 'net/http'
24
+ end
25
+ @proxy = options
26
+ end
27
+
28
+
29
+ def method_missing(id, *args)
30
+ return invoke(id.id2name, args)
31
+ end
32
+
33
+ private
34
+
35
+ def invoke(method, args)
36
+ req_head = { 'Content-Type' => 'application/binary' }
37
+ req_body = Hessian2.call(method, args)
38
+
39
+ if @async
40
+ EM::HttpRequest.new("#{@scheme}://#{@host}:#{@port}#{@path}").apost(body: req_body, head: req_head)
41
+ elsif @fiber_aware
42
+ http = EM::HttpRequest.new("#{@scheme}://#{@host}:#{@port}#{@path}").post(body: req_body, head: req_head)
43
+ Hessian2.parse_rpc(http.response)
44
+ else
45
+ req = Net::HTTP::Post.new(@path, req_head)
46
+ req.basic_auth @user, @password if @user
47
+ conn = Net::HTTP.new(@host, @port, *@proxy.values_at(:host, :port, :user, :password))
48
+ conn.use_ssl = true and conn.verify_mode = OpenSSL::SSL::VERIFY_NONE if @scheme == 'https'
49
+ conn.start do |http|
50
+ res = http.request(req, req_body)
51
+ Hessian2.parse_rpc(res.body)
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+ end