Ruby 中使用 Thrift 实现 RPC 调用

2014/4/2 posted in  Ruby comments

Thrift 框架简介

Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。
详情参考官方文档

定义 .thrift 文件

namespace rb model

struct User {
  1: i32 id,
  2: string name,
}

service UserStorage {
  void set_user(1: User user),
  User get_user(1: i32 id),
}

运行 thrift --gen rb user.thrift,会在 gen-rb 目录下生成 user_constants.rb, user_types.rb, user_storage.rb 三个文件。

定义服务端

# -*- coding: utf-8 -*-
$:.push('gen-rb')

require 'thrift'
require 'user_constants'
require 'user_storage'

class UserHandler
  def set_user(user)
    puts 'Set user: ' + user.inspect
  end

  def get_user(id)
    return Model::User.new(:id => id, :name => "Name: #{id}")
  end
end

processor = Model::UserStorage::Processor.new(UserHandler.new())
transport = Thrift::ServerSocket.new(9090)
transportFactory = Thrift::BufferedTransportFactory.new()
server = Thrift::SimpleServer.new(processor, transport, transportFactory)

puts "Starting the server..."
server.serve()
puts "Stoped the server..."

实现对应的服务操作,并打开 9090 端口等待客户端调用

客户端调用

# -*- coding: utf-8 -*-
$:.push('gen-rb')

require 'thrift'
require 'user_constants'
require 'user_storage'

begin
  transport = Thrift::BufferedTransport.new(Thrift::Socket.new('0.0.0.0', '9090'))
  protocol = Thrift::BinaryProtocol.new(transport)
  client = Model::UserStorage::Client.new(protocol)
  transport.open()

  user = Model::User.new(:id => 1, :name => 'foo')

  puts client.set_user(user).inspect # => nil
  puts client.get_user(2).inspect # => <Model::User id:2, name:"Name: 2">

  transport.close()
rescue Thrift::TransportException => e
  puts "Thrift::Exception: #{e.message}"
end