em_hessian2 2.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f86a3f73d4a240f7d3a6d4ebd13357be4e1d6ebe
4
+ data.tar.gz: ffd3bfa2567ebe5bad5991338109ec0b4f53400b
5
+ SHA512:
6
+ metadata.gz: 87dc2b7e7b3c45dccad5b1f4cb126eba30dbebbc410aad62e55be4022eaf13fc7d3ec3e314beb9ad68acb6809b1f500d7139b5ec7a401bd0ff14b8a00f0a5d93
7
+ data.tar.gz: f3be7a27ba419b4a28826d75a1175686f254bd1cc646a134e04612ef4f5943ba972d9c5930b35162ee99bf4270a9525be6bf5de39609ffc80e09566a00e17549
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ doc/*
5
+ pkg/*
6
+ test/*.data
7
+ test/*.txt
8
+ test/*.yml
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hessian2.gemspec
4
+ gemspec
@@ -0,0 +1,186 @@
1
+ # hessian2
2
+
3
+ like json, additionally, 麻绳2 support structured data, with no schema.
4
+
5
+ hessian2 implements hessian 2.0 protocol. check [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 structured data 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
+ monkey = Monkey.new(born_at: Time.new(2009, 5, 8), name: '大鸡', price: 99.99)
33
+ #=> #<Monkey id: nil, born_at: "2009-05-08 00:00:00", name: "\u5927\u9E21", price: #<BigDecimal:2b7c568,'0.9998999999 999999E2',27(45)>>
34
+
35
+ bin = Hessian2.write(monkey)
36
+ ```
37
+
38
+ ## deserializing
39
+
40
+ ``` ruby
41
+ monkey = Hessian2.parse(bin)
42
+ #=> #<struct id=nil, born_at=2009-05-08 00:00:00 +0800, name="\u5927\u9E21", price=(7036170730324623/70368744177664)>
43
+ ```
44
+
45
+ ## struct wrapper
46
+
47
+ for hash and object, only send values that specified.
48
+
49
+ ``` ruby
50
+ MonkeyStruct = Struct.new(:born_at, :name)
51
+
52
+ wrapped_monkey = Hessian2::StructWrapper.new(MonkeyStruct, monkey)
53
+ bin = Hessian2.write(wrapped_monkey)
54
+ ```
55
+
56
+ parsing values-binary to a monkey struct
57
+
58
+ ``` ruby
59
+ monkey = Hessian2.parse(bin, MonkeyStruct)
60
+ #=> #<struct born_at=2009-05-08 00:00:00 +0800, name="\u5927\u9E21">
61
+ ```
62
+
63
+ monkeys
64
+
65
+ ``` ruby
66
+ wrapped_monkeys = Hessian2::StructWrapper.new([MonkeyStruct], monkeys)
67
+ bin = Hessian2.write(wrapped_monkeys)
68
+
69
+ monkeys = Hessian2.parse(bin, [MonkeyStruct])
70
+ ```
71
+
72
+ struct wrapper supports: hash, object, [hash, [object
73
+
74
+ ## class wrapper
75
+
76
+ for statically typed languages.
77
+
78
+ ``` ruby
79
+ wrapped_monkey = Hessian2::ClassWrapper.new('com.sun.java.Monkey', monkey)
80
+ ```
81
+
82
+ monkeys
83
+
84
+ ``` ruby
85
+ wrapped_monkeys = Hessian2::ClassWrapper.new('[com.sun.java.Monkey', monkeys)
86
+ ```
87
+
88
+ class wrapper supports: hash, object, [hash, [object
89
+
90
+ ## type wrapper
91
+
92
+ wrap a string to long
93
+
94
+ ``` ruby
95
+ str = '-0x8_000_000_000_000_000'
96
+ heslong = Hessian2::TypeWrapper.new(:long, str)
97
+ ```
98
+
99
+ wrap a file to binary
100
+
101
+ ``` ruby
102
+ binstr = IO.binread(File.expand_path("../Lighthouse.jpg", __FILE__))
103
+ hesbin = Hessian2::TypeWrapper.new(:bin, binstr)
104
+ ```
105
+
106
+ there are types: 'L', 'I', 'B', '[L', '[I', '[B', :long, :int, :bin, [:long], [:int], [:bin]
107
+
108
+ ## client
109
+
110
+ ``` ruby
111
+ url = 'http://127.0.0.1:9292/monkey'
112
+ client = Hessian2::Client.new(url)
113
+ ```
114
+
115
+ call remote method, send a monkey
116
+
117
+ ``` ruby
118
+ client.send_monkey(monkey)
119
+ ```
120
+
121
+ ## service
122
+
123
+ extend hessian handler
124
+
125
+ ``` ruby
126
+ class MonkeyService
127
+ extend Hessian2::Handler
128
+
129
+ def self.send_monkey(monkey)
130
+ # ...
131
+ end
132
+ ```
133
+
134
+ handle request in sinatra
135
+
136
+ ``` ruby
137
+ post '/monkey' do
138
+ MonkeyService.handle(request.body.read)
139
+ end
140
+ ```
141
+
142
+ ## test
143
+
144
+ ```
145
+ cd test/
146
+ ```
147
+
148
+ start a service
149
+
150
+ ```
151
+ ruby ./app.rb -o 0.0.0.0 -e production
152
+ ```
153
+
154
+ or
155
+
156
+ ```
157
+ thin start -p 4567 --threaded -e production
158
+ ```
159
+
160
+ test parser
161
+
162
+ ```
163
+ ruby ./get.rb
164
+ ```
165
+
166
+ test writer
167
+
168
+ ```
169
+ ruby ./set.rb
170
+ ```
171
+
172
+ ## todo
173
+
174
+ supports packet and envelope
175
+
176
+ rsa aes encryption
177
+
178
+ write in c
179
+
180
+ ## authors
181
+
182
+ [takafan](http://hululuu.com)
183
+
184
+ ## license
185
+
186
+ [Ruby License](http://www.ruby-lang.org/en/LICENSE.txt)
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "hessian2/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "em_hessian2"
7
+ s.version = Hessian2::VERSION
8
+ s.authors = ["takafan", "ldd600"]
9
+ s.email = ["takafan@163.com"]
10
+ s.homepage = "http://github.com/takafan/hessian2"
11
+ s.summary = %q{Hessian2}
12
+ s.description = %q{json encode fast, hessian write small.}
13
+
14
+ s.rubyforge_project = "em_hessian2"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ #s.add_dependency('faraday')
24
+ s.add_dependency('em-synchrony')
25
+ s.add_dependency('em-http-request')
26
+ #s.add_dependency('eventmachine')
27
+ s.add_runtime_dependency "bigdecimal"
28
+ end
@@ -0,0 +1,14 @@
1
+ require 'hessian2/class_wrapper'
2
+ require 'hessian2/client'
3
+ require 'hessian2/fault'
4
+ require 'hessian2/handler'
5
+ require 'hessian2/hessian_client'
6
+ require 'hessian2/parser'
7
+ require 'hessian2/struct_wrapper'
8
+ require 'hessian2/type_wrapper'
9
+ require 'hessian2/version'
10
+ require 'hessian2/writer'
11
+
12
+ module Hessian2
13
+ extend Parser, Writer
14
+ end
@@ -0,0 +1,8 @@
1
+ module Hessian2
2
+ class ClassWrapper
3
+ attr_accessor :hessian_class, :object
4
+ def initialize(hessian_class, object)
5
+ @hessian_class, @object = hessian_class, object
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,73 @@
1
+ require 'uri'
2
+ # require 'net/http'
3
+ # require 'net/https'
4
+ require 'hessian2'
5
+ #require 'faraday'
6
+ require 'em-synchrony'
7
+ require "em-synchrony/em-http"
8
+ #require "thread"
9
+
10
+ module Hessian2
11
+ class Client
12
+ attr_accessor :user, :password
13
+ attr_reader :scheme, :host, :port, :path, :proxy
14
+
15
+ def initialize(url, proxy = {})
16
+ uri = URI.parse(url)
17
+ @scheme, @host, @port, @path = uri.scheme, uri.host, uri.port, uri.path
18
+ raise "Unsupported Hessian protocol: #{@scheme}" unless %w(http https).include?(@scheme)
19
+ @proxy = proxy
20
+ end
21
+
22
+ def method_missing(id, *args)
23
+ return invoke(id.id2name, args)
24
+ end
25
+
26
+ private
27
+ def invoke(method, args)
28
+ # use em_synchrony direct
29
+ url = "http://#{@host}:#{@port}"
30
+ result = nil
31
+ block = lambda {
32
+ EM::Synchrony.sync EM::HttpRequest.new(url, :connect_timeout => 5, :inactivity_timeout => 60).post(
33
+ :path=>"#{@path}",
34
+ :head=>{'Content-Type' => 'application/binary; charset=utf-8'},
35
+ :body=>Hessian2.call(method, args)
36
+ )
37
+ }
38
+ if !EM.reactor_running?
39
+ EM.synchrony do
40
+ http = block.call
41
+ result = Hessian2.parse_rpc(http.response)
42
+ EM.stop
43
+ end
44
+ else
45
+ http = block.call
46
+ result = Hessian2.parse_rpc(http.response)
47
+ end
48
+ return result
49
+
50
+
51
+ # #use faraday
52
+ # url = "#{@scheme}://#{@host}:#{@port}"
53
+ # conn = Faraday.new(:url => url) do |faraday|
54
+ # # faraday.request :url_encoded # form-encode POST params
55
+ # # faraday.response :logger # log requests to STDOUT
56
+ # faraday.use Faraday::Response::RaiseError # raise exceptions on 40x, 50x responses
57
+ # faraday.use Faraday::Adapter::EMSynchrony
58
+ # #faraday.use_ssl = true and conn.verify_mode = OpenSSL::SSL::VERIFY_NONE if @scheme == 'https'
59
+ # end
60
+
61
+ # response = conn.post do |req|
62
+ # req.url "#{@path}"
63
+ # req.headers['Content-Type'] = 'application/binary; charset=utf-8'
64
+ # req.body = Hessian2.call(method, args)
65
+ # # req.options.timeout = 30 # open/read timeout in seconds
66
+ # # req.options.open_timeout = 5 # connection open timeout in seconds
67
+ # # req.options.proxy = @proxy
68
+ # end
69
+
70
+ # Hessian2.parse_rpc(response.body)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,164 @@
1
+ module Hessian2
2
+ #=== Hessian 2.0 Web Services Protocol Bytecode map
3
+ #
4
+ # x00 - x42 # reserved
5
+ # x43 # rpc call ('C')
6
+ # x44 # reserved
7
+ # x45 # envelope ('E')
8
+ # x46 # fault ('F')
9
+ # x47 # reserved
10
+ # x48 # hessian version ('H')
11
+ # x49 - x4f # reserved
12
+ # x4f # packet chunk ('O')
13
+ # x50 # packet end ('P')
14
+ # x51 # reserved
15
+ # x52 # rpc result ('R')
16
+ # x53 - x59 # reserved
17
+ # x5a # terminator ('Z')
18
+ # x5b - x5f # reserved
19
+ # x70 - x7f # final packet (0 - 4096)
20
+ # x80 - xff # final packet for envelope (0 - 127)
21
+ #
22
+ #=== Hessian 2.0 Serialization Protocol Bytecode map
23
+ #
24
+ # x00 - x1f # utf-8 string length 0-31
25
+ # x20 - x2f # binary data length 0-15
26
+ # x30 - x33 # utf-8 string length 0-1023
27
+ # x34 - x37 # binary data length 0-1023
28
+ # x38 - x3f # three-octet compact long (-x40000 to x3ffff)
29
+ # x40 # reserved (expansion/escape)
30
+ # x41 # 8-bit binary data non-final chunk ('A')
31
+ # x42 # 8-bit binary data final chunk ('B')
32
+ # x43 # object type definition ('C')
33
+ # x44 # 64-bit IEEE encoded double ('D')
34
+ # x45 # reserved
35
+ # x46 # boolean false ('F')
36
+ # x47 # reserved
37
+ # x48 # untyped map ('H')
38
+ # x49 # 32-bit signed integer ('I')
39
+ # x4a # 64-bit UTC millisecond date
40
+ # x4b # 32-bit UTC minute date
41
+ # x4c # 64-bit signed long integer ('L')
42
+ # x4d # map with type ('M')
43
+ # x4e # null ('N')
44
+ # x4f # object instance ('O')
45
+ # x50 # reserved
46
+ # x51 # reference to map/list/object - integer ('Q')
47
+ # x52 # utf-8 string non-final chunk ('R')
48
+ # x53 # utf-8 string final chunk ('S')
49
+ # x54 # boolean true ('T')
50
+ # x55 # variable-length list/vector ('U')
51
+ # x56 # fixed-length list/vector ('V')
52
+ # x57 # variable-length untyped list/vector ('W')
53
+ # x58 # fixed-length untyped list/vector ('X')
54
+ # x59 # long encoded as 32-bit int ('Y')
55
+ # x5a # list/map terminator ('Z')
56
+ # x5b # double 0.0
57
+ # x5c # double 1.0
58
+ # x5d # double represented as byte (-128.0 to 127.0)
59
+ # x5e # double represented as short (-32768.0 to 32767.0)
60
+ # x5f # double represented as float
61
+ # x60 - x6f # object with direct type
62
+ # x70 - x77 # fixed list with direct length
63
+ # x78 - x7f # fixed untyped list with direct length
64
+ # x80 - xbf # one-octet compact int (-x10 to x3f, x90 is 0)
65
+ # xc0 - xcf # two-octet compact int (-x800 to x7ff)
66
+ # xd0 - xd7 # three-octet compact int (-x40000 to x3ffff)
67
+ # xd8 - xef # one-octet compact long (-x8 to xf, xe0 is 0)
68
+ # xf0 - xff # two-octet compact long (-x800 to x7ff, xf8 is 0)
69
+ module Constants
70
+ BC_BINARY = 0x42
71
+ BC_BINARY_CHUNK = 0x41
72
+ BC_BINARY_DIRECT = 0x20
73
+ BINARY_DIRECT_MAX = 0x0f
74
+ BC_BINARY_SHORT = 0x34
75
+ BINARY_SHORT_MAX = 0x3ff
76
+
77
+ BC_CLASS_DEF = 0x43
78
+
79
+ BC_DATE = 0x4a
80
+ BC_DATE_MINUTE = 0x4b
81
+
82
+ BC_DOUBLE = 0x44
83
+
84
+ BC_DOUBLE_ZERO = 0x5b
85
+ BC_DOUBLE_ONE = 0x5c
86
+ BC_DOUBLE_BYTE = 0x5d
87
+ BC_DOUBLE_SHORT = 0x5e
88
+ BC_DOUBLE_MILL = 0x5f
89
+
90
+ BC_FALSE = 0x46
91
+
92
+ BC_INT = 0x49
93
+
94
+ INT_DIRECT_MIN = -0x10
95
+ INT_DIRECT_MAX = 0x2f
96
+ BC_INT_ZERO = 0x90
97
+
98
+ INT_BYTE_MIN = -0x800
99
+ INT_BYTE_MAX = 0x7ff
100
+ BC_INT_BYTE_ZERO = 0xc8
101
+
102
+ BC_END = 0x5a
103
+
104
+ INT_SHORT_MIN = -0x40000
105
+ INT_SHORT_MAX = 0x3ffff
106
+ BC_INT_SHORT_ZERO = 0xd4
107
+
108
+ BC_LIST_VARIABLE = 0x55
109
+ BC_LIST_FIXED = 0x56
110
+ BC_LIST_VARIABLE_UNTYPED = 0x57
111
+ BC_LIST_FIXED_UNTYPED = 0x58
112
+
113
+ BC_LIST_DIRECT = 0x70
114
+ BC_LIST_DIRECT_UNTYPED = 0x78
115
+ LIST_DIRECT_MAX = 0x7
116
+
117
+ BC_LONG = 0x4c
118
+ LONG_DIRECT_MIN = -0x08
119
+ LONG_DIRECT_MAX = 0x0f
120
+ BC_LONG_ZERO = 0xe0
121
+
122
+ LONG_BYTE_MIN = -0x800
123
+ LONG_BYTE_MAX = 0x7ff
124
+ BC_LONG_BYTE_ZERO = 0xf8
125
+
126
+ LONG_SHORT_MIN = -0x40000
127
+ LONG_SHORT_MAX = 0x3ffff
128
+ BC_LONG_SHORT_ZERO = 0x3c
129
+
130
+ BC_LONG_INT = 0x59
131
+
132
+ BC_MAP = 0x4d
133
+ BC_MAP_UNTYPED = 0x48
134
+
135
+ BC_NULL = 0x4e
136
+
137
+ BC_OBJECT = 0x4f
138
+ BC_OBJECT_DEF = 0x43
139
+
140
+ BC_OBJECT_DIRECT = 0x60
141
+ OBJECT_DIRECT_MAX = 0x0f
142
+
143
+ BC_REF = 0x51
144
+
145
+ BC_STRING = 0x53
146
+ BC_STRING_CHUNK = 0x52
147
+
148
+ BC_STRING_DIRECT = 0x00
149
+ STRING_DIRECT_MAX = 0x1f
150
+ BC_STRING_SHORT = 0x30
151
+ STRING_SHORT_MAX = 0x3ff
152
+
153
+ BC_TRUE = 0x54
154
+
155
+ P_PACKET_CHUNK = 0x4f
156
+ P_PACKET = 0x50
157
+
158
+ P_PACKET_DIRECT = 0x80
159
+ PACKET_DIRECT_MAX = 0x7f
160
+
161
+ P_PACKET_SHORT = 0x70
162
+ PACKET_SHORT_MAX = 0xfff
163
+ end
164
+ end