Ruby On gRpc
在ruby中使用gRpc需要先安装Protocol Buffters和对应的支持库,Protocol Buffters上文有介绍如何安装,这里介绍支持库的安装
安装支持库
source 'https://rubygems.org' # 可以换清华源或者科学上网
gem 'grpc' # gRPC 库
gem 'google-protobuf' # Protobuf 库
gem 'grpc-tools' # gRPC 工具
生成代码
通过grpc-tools将代码生成出来,生成的代码位置于指定目录
grpc_tools_ruby_protoc -I .proto所在目录 --ruby_out=生成的实体类目录 --grpc_out=生成的服务目录 ./需要编译的.proto文件
# grpc_tools_ruby_protoc -I ./ --ruby_out=./ --grpc_out=./ ./studyProto.proto
*** 注意***:grpc-tools生成的文件默认导入目录是在根目录,这就导致可能会出现找不到文件的异常 require': cannot load such file -- studyProto_pb (LoadError)
,需要手动修改生成的xx_services_pb.rb
这个文件
require 'grpc'
# require 'studyProto_pb'
require_relative 'studyProto_pb' # 改一下导入方法即可
客户端
单一请求客户端
require 'grpc'
require_relative 'studyProto_services_pb'
# 创建 gRPC stub,指定服务端的地址和端口
stub = Com::Llllluuusa(配置的包名)::服务名::Stub.new(
'localhost:8080',
:this_channel_is_insecure,
# interceptors: [拦截器r.new],
)
# 构造请求消息
request = Com::Llllluuusa(配置的包名)::请求名.new(message: '我是请求消息')
# 调用服务方法并接收响应
begin
response = stub.服务方法(request)
puts "服务端响应结果: #{response.reply}"
rescue GRPC::BadStatus => e
puts "服务端响应失败: #{e.details}"
end
流式请求客户端
require 'grpc'
require_relative 'studyProto_services_pb'
# 创建客户端 Stub
stub = Com::Llllluuusa(配置的包名)::服务名::Stub.new(
'localhost:8080',
:this_channel_is_insecure,
# interceptors: [拦截器r.new],
)
# 准备一个 Enumerator 来提供客户端的请求流
requests = Enumerator.new do |yielder|
yielder << Com::Llllluuusa(配置的包名)::请求名.new(message: '我是请求消息1')
sleep 1
yielder << Com::Llllluuusa(配置的包名)::请求名.new(message: '我是请求消息2')
sleep 1
yielder << Com::Llllluuusa(配置的包名)::请求名.new(message: '我是请求消息3')
end
# 发起双向流式/客户端流式调用
response_stream = stub.服务方法(requests)
# 发起服务端流式调用
# request = Com::Llllluuusa(配置的包名)::请求名.new(message: '我是请求消息')
# response_stream = stub.服务方法(request)
# 读取服务器的响应流
begin
response_stream.each do |response|
puts "服务端响应结果: #{response.reply}"
end
rescue GRPC::BadStatus => e
puts "服务端响应失败: #{e.details}"
end
服务端
单一请求服务端
require 'grpc'
require_relative 'study_services_pb' # 生成的 gRPC 服务文件
# 实现服务类,继承自生成的服务
class 服务端Server < Com::Llllluuusa(配置的包名)::服务名::Service
# 实现普通 RPC 方法
def 服务方法(request, _unused_call)
# 处理客户端请求,返回响应
puts "客户端发送的请求: #{request.message}"
Com::Llllluuusa(配置的包名)::响应名.new(reply: "我是响应结果")
end
end
流式请求服务端
require 'grpc'
require_relative 'study_services_pb' # 生成的 gRPC 服务文件
# 实现服务类,继承自生成的服务
class 服务端Server < Com::Llllluuusa(配置的包名)::服务名::Service
# 实现普通 RPC 方法
def 服务方法(call)
# 处理客户端请求流
call.each_remote_read do |request|
puts "客户端发送的请求: #{request.message}"
end
# 返回响应
yield Com::Example::StudyResponse.new(reply: "我是响应结果1")
yield Com::Example::StudyResponse.new(reply: "我是响应结果2")
yield Com::Example::StudyResponse.new(reply: "我是响应结果3")
end
end
拦截器
服务端拦截器
class XxInterceptor < GRPC::ServerInterceptor
def request_response(request, metadata: {}, &block)
# 打印调用的方法名称
puts "Calling method: #{metadata['grpc.method']}"
# 调用 RPC 方法
yield(request, metadata, &block)
end
end
客户端拦截器
require 'grpc'
class XxInterceptor < GRPC::ClientInterceptor
def request_response(request, metadata: {}, &block)
# 获取当前调用的方法名称
puts "Calling method: #{metadata['grpc.method']}"
# 调用 RPC 方法
response = yield(request, metadata, &block)
# 返回响应
response
end
end
启动类
require 'grpc'
require_relative '服务端Server' # 服务端接口
# 启动 gRPC 服务器
# server = GRPC::RpcServer.new(interceptors: [拦截器.new])
server = GRPC::RpcServer.new
server.add_http2_port('0.0.0.0:8080', :this_port_is_insecure)
server.handle(服务端Server)
puts 'gRpc服务启动...'
server.run_till_terminated