grpc_kit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +70 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +45 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/examples/helloworld/helloworld.proto +37 -0
- data/examples/helloworld/helloworld_pb.rb +18 -0
- data/examples/helloworld/helloworld_services_pb.rb +22 -0
- data/examples/helloworld_client.rb +12 -0
- data/examples/helloworld_server.rb +25 -0
- data/examples/routeguide/routeguide.json +601 -0
- data/examples/routeguide/routeguide.proto +110 -0
- data/examples/routeguide/routeguide_pb.rb +37 -0
- data/examples/routeguide/routeguide_services_pb.rb +61 -0
- data/examples/routeguide_client.rb +23 -0
- data/examples/routeguide_server.rb +35 -0
- data/grpc_kit.gemspec +35 -0
- data/lib/grpc.rb +7 -0
- data/lib/grpc_kit.rb +17 -0
- data/lib/grpc_kit/client.rb +107 -0
- data/lib/grpc_kit/errors.rb +25 -0
- data/lib/grpc_kit/grpc/dsl.rb +87 -0
- data/lib/grpc_kit/grpc/generic_service.rb +26 -0
- data/lib/grpc_kit/grpc/stream.rb +22 -0
- data/lib/grpc_kit/io/basic.rb +35 -0
- data/lib/grpc_kit/rpc_desc.rb +72 -0
- data/lib/grpc_kit/server.rb +76 -0
- data/lib/grpc_kit/session/client.rb +107 -0
- data/lib/grpc_kit/session/server.rb +155 -0
- data/lib/grpc_kit/session/stream.rb +68 -0
- data/lib/grpc_kit/status_codes.rb +24 -0
- data/lib/grpc_kit/version.rb +5 -0
- metadata +208 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/errors'
|
4
|
+
require 'grpc_kit/rpc_desc'
|
5
|
+
require 'grpc_kit/client'
|
6
|
+
require 'grpc_kit/grpc/stream'
|
7
|
+
|
8
|
+
module GrpcKit
|
9
|
+
module GRPC
|
10
|
+
module Dsl
|
11
|
+
attr_accessor :service_name
|
12
|
+
|
13
|
+
attr_writer :marshal_class_method, :unmarshal_class_method
|
14
|
+
|
15
|
+
def inherited(subclass)
|
16
|
+
subclass.rpc_descs.merge!(rpc_descs)
|
17
|
+
subclass.service_name = service_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def rpc(name, input, output)
|
21
|
+
if rpc_descs.key?(name)
|
22
|
+
raise "rpc (#{name}) is already defined"
|
23
|
+
end
|
24
|
+
|
25
|
+
unless input.respond_to?(@marshal_class_method)
|
26
|
+
raise "#{marshal} must implement #{marshal}.#{@marshal_class_method}"
|
27
|
+
end
|
28
|
+
|
29
|
+
unless output.respond_to?(@unmarshal_class_method)
|
30
|
+
raise "#{unmarshal} must implement #{unmarshal}.#{@unmarshal_class_method}"
|
31
|
+
end
|
32
|
+
|
33
|
+
# create StreamDesc?
|
34
|
+
rpc_descs[name] = GrpcKit::RpcDesc.new(
|
35
|
+
name: name,
|
36
|
+
input: input,
|
37
|
+
output: output,
|
38
|
+
marshal_method: @marshal_class_method,
|
39
|
+
unmarshal_method: @unmarshal_class_method,
|
40
|
+
)
|
41
|
+
|
42
|
+
define_method(rpc_descs[name].ruby_style_name) do |_, _|
|
43
|
+
raise GrpcKit::Errors::Unimplemented, name.to_s
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def stream(cls)
|
48
|
+
GrpcKit::GRPC::Stream.new(cls)
|
49
|
+
end
|
50
|
+
|
51
|
+
def rpc_stub_class
|
52
|
+
rpc_descs_ = rpc_descs
|
53
|
+
service_name_ = service_name
|
54
|
+
Class.new(GrpcKit::Client) do
|
55
|
+
rpc_descs_.each_pair do |_, rpc_desc|
|
56
|
+
method_name = rpc_desc.ruby_style_name
|
57
|
+
path = rpc_desc.path(service_name_)
|
58
|
+
|
59
|
+
if rpc_desc.request_response?
|
60
|
+
define_method(method_name) do |request, opts = {}|
|
61
|
+
request_response(path, request, rpc_desc, opts)
|
62
|
+
end
|
63
|
+
elsif rpc_desc.client_streamer?
|
64
|
+
define_method(method_name) do |requests, opts = {}|
|
65
|
+
client_streamer(path, requests, rpc_desc, opts)
|
66
|
+
end
|
67
|
+
elsif rpc_desc.server_streamer?
|
68
|
+
define_method(method_name) do |request, opts = {}, &blk|
|
69
|
+
server_streamer(path, request, rpc_desc, opts, &blk)
|
70
|
+
end
|
71
|
+
elsif rpc_desc.bidi_streamer?
|
72
|
+
define_method(method_name) do |requests, opts = {}, &blk|
|
73
|
+
bidi_streamer(path, requests, rpc_desc, opts, &blk)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
raise "unknown #{rpc_desc}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def rpc_descs
|
83
|
+
@rpc_descs ||= {}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/grpc/dsl'
|
4
|
+
|
5
|
+
module GrpcKit
|
6
|
+
module GRPC
|
7
|
+
module GenericService
|
8
|
+
def self.included(obj)
|
9
|
+
obj.extend(GrpcKit::GRPC::Dsl)
|
10
|
+
return unless obj.service_name.nil?
|
11
|
+
|
12
|
+
# if obj.name.nil?
|
13
|
+
# obj.service_name = 'GenericService'
|
14
|
+
# else
|
15
|
+
# modules = obj.name.split('::')
|
16
|
+
# obj.service_name =
|
17
|
+
# if modules.length > 2
|
18
|
+
# modules[modules.length - 2]
|
19
|
+
# else
|
20
|
+
# modules.first
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/grpc/dsl'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
module GrpcKit
|
7
|
+
module GRPC
|
8
|
+
class Stream
|
9
|
+
extend Forwardable
|
10
|
+
delegate %i[encode decode] => :@klass
|
11
|
+
|
12
|
+
def initialize(klass)
|
13
|
+
@klass = klass
|
14
|
+
end
|
15
|
+
|
16
|
+
# FIXME: Do not use method_missing...
|
17
|
+
def method_missing(name, *args, &block)
|
18
|
+
@klass.send(name, *args, &block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ds9'
|
4
|
+
|
5
|
+
module GrpcKit
|
6
|
+
module IO
|
7
|
+
class Basic
|
8
|
+
def initialize(reader, writer)
|
9
|
+
@reader = reader
|
10
|
+
@writer = writer
|
11
|
+
end
|
12
|
+
|
13
|
+
def read(length)
|
14
|
+
data = @reader.read_nonblock(length, nil, exception: false)
|
15
|
+
|
16
|
+
case data
|
17
|
+
when :wait_readable
|
18
|
+
DS9::ERR_WOULDBLOCK
|
19
|
+
when nil
|
20
|
+
''
|
21
|
+
else
|
22
|
+
data
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def write(data)
|
27
|
+
@writer.write(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def wait_readable
|
31
|
+
@reader.wait_writable
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/grpc/stream'
|
4
|
+
|
5
|
+
module GrpcKit
|
6
|
+
class RpcDesc
|
7
|
+
def initialize(name:, input:, output:, marshal_method:, unmarshal_method:)
|
8
|
+
@name = name
|
9
|
+
@input = input
|
10
|
+
@output = output
|
11
|
+
@marshal_method = marshal_method
|
12
|
+
@unmarshal_method = unmarshal_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def encode(val)
|
16
|
+
@output.send(@marshal_method, val)
|
17
|
+
end
|
18
|
+
|
19
|
+
def decode(val)
|
20
|
+
@input.send(@unmarshal_method, val)
|
21
|
+
end
|
22
|
+
|
23
|
+
def encode2(val)
|
24
|
+
@input.send(@marshal_method, val)
|
25
|
+
end
|
26
|
+
|
27
|
+
def decode2(val)
|
28
|
+
@output.send(@unmarshal_method, val)
|
29
|
+
end
|
30
|
+
|
31
|
+
def invoke(rpc, val)
|
32
|
+
args = decode(val)
|
33
|
+
ret = rpc.send(to_underscore(@name), args, nil) # nil is GRPC::Call object
|
34
|
+
encode(ret)
|
35
|
+
end
|
36
|
+
|
37
|
+
def ruby_style_name
|
38
|
+
@ruby_style_name ||= to_underscore(@name).to_sym
|
39
|
+
end
|
40
|
+
|
41
|
+
def path(service_name)
|
42
|
+
"/#{service_name}/#{@name}".to_sym
|
43
|
+
end
|
44
|
+
|
45
|
+
def request_response?
|
46
|
+
!@input.is_a?(GrpcKit::GRPC::Stream) && !@output.is_a?(GrpcKit::GRPC::Stream)
|
47
|
+
end
|
48
|
+
|
49
|
+
def client_streamer?
|
50
|
+
@input.is_a?(GrpcKit::GRPC::Stream) && !@output.is_a?(GrpcKit::GRPC::Stream)
|
51
|
+
end
|
52
|
+
|
53
|
+
def server_streamer?
|
54
|
+
!@input.is_a?(GrpcKit::GRPC::Stream) && @output.is_a?(GrpcKit::GRPC::Stream)
|
55
|
+
end
|
56
|
+
|
57
|
+
def bidi_streamer?
|
58
|
+
@input.is_a?(GrpcKit::GRPC::Stream) && @output.is_a?(GrpcKit::GRPC::Stream)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def to_underscore(val)
|
64
|
+
val
|
65
|
+
.to_s
|
66
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
67
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
68
|
+
.tr('-', '_')
|
69
|
+
.downcase
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grpc_kit/io/basic'
|
4
|
+
require 'grpc_kit/session/server'
|
5
|
+
|
6
|
+
module GrpcKit
|
7
|
+
class Server
|
8
|
+
def initialize
|
9
|
+
@sessions = []
|
10
|
+
@handler = {}
|
11
|
+
@rpc_descs = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
# @params handler [object]
|
15
|
+
def handle(handler)
|
16
|
+
klass = handler.class
|
17
|
+
|
18
|
+
klass.rpc_descs.values.each do |rpc_desc|
|
19
|
+
path = rpc_desc.path(klass.service_name)
|
20
|
+
if @rpc_descs[path]
|
21
|
+
raise "Duplicated method registered #{key}, class: #{handler}"
|
22
|
+
end
|
23
|
+
|
24
|
+
@rpc_descs[path] = [rpc_desc, handler]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
GrpcKit.logger.info("Start grpc_kit v#{GrpcKit::VERSION}")
|
30
|
+
# XXX
|
31
|
+
end
|
32
|
+
|
33
|
+
def stop
|
34
|
+
GrpcKit.logger.info('Stop grpc_kit')
|
35
|
+
|
36
|
+
@sessions.each(&:stop)
|
37
|
+
end
|
38
|
+
|
39
|
+
def session_start(conn, io = GrpcKit::IO::Basic)
|
40
|
+
session = GrpcKit::Session::Server.new(io.new(conn, conn), self) # TODO: change self to proper object
|
41
|
+
@sessions << session
|
42
|
+
|
43
|
+
session.submit_settings([])
|
44
|
+
session.start # blocking
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_data_chunk_recv(stream, data)
|
48
|
+
compressed, length, buf = data.unpack('CNa*')
|
49
|
+
if compressed == 0 # TODO: not
|
50
|
+
if length != buf.size
|
51
|
+
raise 'recived data inconsistent'
|
52
|
+
end
|
53
|
+
|
54
|
+
stream.recv(buf)
|
55
|
+
else
|
56
|
+
raise 'not supported'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def on_frame_data_recv(stream)
|
61
|
+
return unless stream.exist_data?
|
62
|
+
|
63
|
+
path = stream.headers[':path']
|
64
|
+
rpc = @rpc_descs[path.to_sym]
|
65
|
+
if rpc
|
66
|
+
resp = rpc[0].invoke(rpc[1], stream.data)
|
67
|
+
buf = [0, resp.length, resp].pack('CNa*')
|
68
|
+
stream.data = ''
|
69
|
+
stream.send(StringIO.new(buf))
|
70
|
+
else
|
71
|
+
# TODO: 404
|
72
|
+
raise "unkown path #{path}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ds9'
|
4
|
+
require 'grpc_kit/session/stream'
|
5
|
+
|
6
|
+
module GrpcKit
|
7
|
+
module Session
|
8
|
+
class Client < DS9::Client
|
9
|
+
# @io [GrpcKit::IO::XXX]
|
10
|
+
def initialize(io, handler)
|
11
|
+
super() # initialize DS9::Session
|
12
|
+
|
13
|
+
@io = io
|
14
|
+
@streams = {}
|
15
|
+
@handler = handler
|
16
|
+
end
|
17
|
+
|
18
|
+
def start(stream_id)
|
19
|
+
stream = GrpcKit::Session::Stream.new(stream_id: stream_id)
|
20
|
+
@streams[stream_id] = stream
|
21
|
+
|
22
|
+
while want_read? || want_write?
|
23
|
+
if stream.closed?
|
24
|
+
break
|
25
|
+
elsif !stream.exist_data?
|
26
|
+
receive
|
27
|
+
|
28
|
+
send
|
29
|
+
else
|
30
|
+
break
|
31
|
+
# GrpcKit.logger.info("unknown #{stream}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
# invalid if receive and send are not called
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# for nghttp2_session_callbacks_set_send_callback
|
40
|
+
# override
|
41
|
+
def send_event(string)
|
42
|
+
@io.write(string)
|
43
|
+
end
|
44
|
+
|
45
|
+
# for nghttp2_session_callbacks_set_recv_callback
|
46
|
+
# override
|
47
|
+
def recv_event(length)
|
48
|
+
@io.read(length)
|
49
|
+
end
|
50
|
+
|
51
|
+
# for nghttp2_session_callbacks_set_on_data_chunk_recv_callback
|
52
|
+
def on_data_chunk_recv(stream_id, data, flags)
|
53
|
+
@handler.on_data_chunk_recv(@streams[stream_id], data)
|
54
|
+
end
|
55
|
+
|
56
|
+
# provider for nghttp2_submit_response
|
57
|
+
# def on_data_source_read(stream_id, length)
|
58
|
+
# end
|
59
|
+
|
60
|
+
# for nghttp2_session_callbacks_set_on_frame_send_callback
|
61
|
+
# def on_frame_recv(frame)
|
62
|
+
# GrpcKit.logger.debug("on_frame_recv #{frame}")
|
63
|
+
# end
|
64
|
+
|
65
|
+
# # for nghttp2_session_callbacks_set_on_frame_not_send_callback
|
66
|
+
# def on_frame_not_send(frame, reason)
|
67
|
+
# end
|
68
|
+
|
69
|
+
# # for nghttp2_session_callbacks_set_on_frame_send_callback
|
70
|
+
# def on_frame_send(frame, reason)
|
71
|
+
# end
|
72
|
+
|
73
|
+
# # for nghttp2_session_callbacks_set_on_header_callback
|
74
|
+
# def on_header(name, value, frame, flags)
|
75
|
+
# end
|
76
|
+
|
77
|
+
# # for nghttp2_session_callbacks_set_on_begin_headers_callback
|
78
|
+
# def on_begin_header(name, value, frame, flags)
|
79
|
+
# end
|
80
|
+
|
81
|
+
# # for nghttp2_session_callbacks_set_on_begin_frame_callback
|
82
|
+
# def on_begin_frame(frame_header)
|
83
|
+
# end
|
84
|
+
|
85
|
+
# # for nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
|
86
|
+
# def on_invalid_frame_recv(frame, error_code)
|
87
|
+
# end
|
88
|
+
|
89
|
+
# for nghttp2_session_callbacks_set_on_stream_close_callback
|
90
|
+
def on_stream_close(stream_id, error_code)
|
91
|
+
GrpcKit.logger.debug("on_stream_close stream_id=#{stream_id}, error_code=#{error_code}")
|
92
|
+
stream = @streams.delete(stream_id)
|
93
|
+
if stream
|
94
|
+
stream.close
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# # for nghttp2_session_callbacks_set_on_data_chunk_recv_callback
|
99
|
+
# def on_data_chunk_recv(id, data, flags)
|
100
|
+
# end
|
101
|
+
|
102
|
+
# # nghttp2_session_callbacks_set_before_frame_send_callback
|
103
|
+
# def before_frame_send(frame)
|
104
|
+
# end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ds9'
|
4
|
+
require 'grpc_kit/session/stream'
|
5
|
+
|
6
|
+
module GrpcKit
|
7
|
+
module Session
|
8
|
+
class Server < DS9::Server
|
9
|
+
# @io [GrpcKit::IO::XXX]
|
10
|
+
def initialize(io, handler)
|
11
|
+
super() # initialize DS9::Server
|
12
|
+
|
13
|
+
@io = io
|
14
|
+
@streams = {}
|
15
|
+
@stop = false
|
16
|
+
@handler = handler
|
17
|
+
end
|
18
|
+
|
19
|
+
def start
|
20
|
+
@io.wait_readable
|
21
|
+
until @stop && (want_read? || want_write?)
|
22
|
+
if want_write?
|
23
|
+
send
|
24
|
+
end
|
25
|
+
|
26
|
+
if want_read?
|
27
|
+
receive
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop
|
33
|
+
@stop = true
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# provider for nghttp2_submit_response
|
39
|
+
# override
|
40
|
+
def on_data_source_read(stream_id, length)
|
41
|
+
GrpcKit.logger.debug("on_data_source_read #{stream_id}, lenght=#{length}")
|
42
|
+
|
43
|
+
data = @streams[stream_id].read(length)
|
44
|
+
if data.nil?
|
45
|
+
submit_trailer(stream_id, 'grpc-status' => '0')
|
46
|
+
false # nil mean END_STREAM
|
47
|
+
else
|
48
|
+
data
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# for nghttp2_session_callbacks_set_send_callback
|
53
|
+
# override
|
54
|
+
def send_event(string)
|
55
|
+
GrpcKit.logger.debug('send_event')
|
56
|
+
|
57
|
+
@io.write(string)
|
58
|
+
end
|
59
|
+
|
60
|
+
# for nghttp2_session_callbacks_set_recv_callback
|
61
|
+
# override
|
62
|
+
def recv_event(length)
|
63
|
+
# GrpcKit.logger.debug("recv_event #{length}")
|
64
|
+
@io.read(length)
|
65
|
+
end
|
66
|
+
|
67
|
+
# for nghttp2_session_callbacks_set_on_frame_send_callback
|
68
|
+
def on_frame_recv(frame)
|
69
|
+
GrpcKit.logger.debug("on_frame_recv #{frame}")
|
70
|
+
case frame
|
71
|
+
when DS9::Frames::Data
|
72
|
+
# need to port NGHTTP2_FLAG_END_STREAM to check frame.flag has it
|
73
|
+
stream = @streams[frame.stream_id]
|
74
|
+
resp = @handler.on_frame_data_recv(stream)
|
75
|
+
unless resp
|
76
|
+
return # TODO
|
77
|
+
end
|
78
|
+
|
79
|
+
submit_response(
|
80
|
+
frame.stream_id,
|
81
|
+
':status' => '200',
|
82
|
+
'content-type' => 'application/grpc',
|
83
|
+
'accept-encoding' => 'identity,gzip',
|
84
|
+
)
|
85
|
+
# when DS9::Frames::Headers
|
86
|
+
# need to port NGHTTP2_FLAG_END_STREAM to check frame.flag has it
|
87
|
+
# when DS9::Frames::Goaway
|
88
|
+
# when DS9::Frames::RstStream
|
89
|
+
else
|
90
|
+
GrpcKit.logger.info("unsupport frame #{frame}")
|
91
|
+
end
|
92
|
+
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
# for nghttp2_session_callbacks_set_on_frame_send_callback
|
97
|
+
def on_frame_send(frame)
|
98
|
+
GrpcKit.logger.debug("on_frame_send #{frame}")
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
# for nghttp2_session_callbacks_set_on_frame_not_send_callback
|
103
|
+
def on_frame_not_send(frame, reason)
|
104
|
+
GrpcKit.logger.debug("on_frame_not_send frame=#{frame}, reason=#{reason}")
|
105
|
+
true
|
106
|
+
end
|
107
|
+
|
108
|
+
# for nghttp2_session_callbacks_set_on_begin_headers_callback
|
109
|
+
def on_begin_headers(header)
|
110
|
+
stream_id = header.stream_id
|
111
|
+
GrpcKit.logger.debug("on_begin_header stream_id=#{stream_id}")
|
112
|
+
|
113
|
+
if @streams[stream_id]
|
114
|
+
raise "#{stream_id} is already existed"
|
115
|
+
end
|
116
|
+
|
117
|
+
@streams[stream_id] = GrpcKit::Session::Stream.new(stream_id: stream_id)
|
118
|
+
end
|
119
|
+
|
120
|
+
# for nghttp2_session_callbacks_set_on_header_callback
|
121
|
+
def on_header(name, value, frame, _flags)
|
122
|
+
@streams[frame.stream_id].headers[name] = value
|
123
|
+
end
|
124
|
+
|
125
|
+
# for nghttp2_session_callbacks_set_on_begin_frame_callback
|
126
|
+
def on_begin_frame(frame_header)
|
127
|
+
GrpcKit.logger.debug("on_begin_frame #{frame_header}")
|
128
|
+
true
|
129
|
+
end
|
130
|
+
|
131
|
+
# for nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
|
132
|
+
def on_invalid_frame_recv(frame, error_code)
|
133
|
+
GrpcKit.logger.debug("on_invalid_frame_recv #{error_code}")
|
134
|
+
true
|
135
|
+
end
|
136
|
+
|
137
|
+
# for nghttp2_session_callbacks_set_on_stream_close_callback
|
138
|
+
def on_stream_close(stream_id, error_code)
|
139
|
+
GrpcKit.logger.debug("on_stream_close stream_id=#{stream_id}, error_code=#{error_code}")
|
140
|
+
@streams.delete(stream_id)
|
141
|
+
end
|
142
|
+
|
143
|
+
# for nghttp2_session_callbacks_set_on_data_chunk_recv_callback
|
144
|
+
def on_data_chunk_recv(stream_id, data, _flags)
|
145
|
+
@handler.on_data_chunk_recv(@streams[stream_id], data)
|
146
|
+
end
|
147
|
+
|
148
|
+
# nghttp2_session_callbacks_set_before_frame_send_callback
|
149
|
+
def before_frame_send(frame)
|
150
|
+
GrpcKit.logger.debug("before_frame_send frame=#{frame}")
|
151
|
+
true
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|