使用 Thrift

Thrift是一个用于不同语言间通讯的开发框架。

首先用Thrift的语法定义好交互细节,命名为hello.thrift

namespace php hello

enum SexType {
  MALE = 1,
  FEMALE = 2
}

struct User {
  1: string firstname,
  2: string lastname,
  3: i32 user_id = 0,
  4: SexType sex,
  5: bool active = false,
  6: optional string description
}

exception InvalidValueException {
  1: i32 error_code,
  2: string error_msg
}

service UserExchange {
  void ping(),
  i32 add_user(1:User u) throws (1: InvalidValueException e),
  User get_user(1:i32 uid) throws (1: InvalidValueException e),
  oneway void clear_list()
}

生成php文件

thrift -r --gen php hello.thrift

生成python文件

thrift -r --gen py hello.thrift

python服务端,命名为python_server.py

#!/usr/bin/env python

import sys
sys.path.append('./gen-py')

from hello import UserExchange
from hello.ttypes import *

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

users = []

class UserManagerHandler:
    def __init__(self):
        pass
        #self.log = {}

    def ping(self):
        print 'ping()'

    def add_user(self, user):
        if user.firstname == None:
            raise InvalidValueException(1,'no firstname exception')
        if user.lastname == None:
            raise InvalidValueException(2, 'no lastname exception')
        if user.user_id <= 0:
            raise InvalidValueException(3, 'wrong user_id')
        if user.sex != SexType.MALE and user.sex != SexType.FEMALE:
            raise InvalidValueException(4, 'wrong sex id')
        print 'Processing user '+user.firstname+' '+user.lastname
        users.append(user)
        print users
        return True

    def get_user(self, user_id):
        if user_id < 0:
            raise InvalidValueException(5, 'wrong id')
        return users[user_id]
        
    def clear_list(self):
        print 'Clearing list'
        print users
        del users [:]
        print users



handler = UserManagerHandler()
processor = UserExchange.Processor(handler)
transport = TSocket.TServerSocket(port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

# You could do one of these for a multithreaded server
#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)

print 'Starting the server...'
server.serve()
print 'done.'

php客户端,命名为php_client.php

<?php

require_once __DIR__.'/lib/Thrift/ClassLoader/ThriftClassLoader.php';

use Thrift\ClassLoader\ThriftClassLoader;

$loader = new ThriftClassLoader();
$loader->registerNamespace('Thrift', __DIR__ . '/lib');
$loader->registerDefinition("tService", realpath(__DIR__ . "/gen-php"));
$loader->register();

use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TSocket;
use Thrift\Transport\THttpClient;
use Thrift\Transport\TBufferedTransport;
use Thrift\Exception\TException;

require_once __DIR__ . "/gen-php/hello/userExchange.php";
require_once __DIR__ . "/gen-php/hello/Types.php";

try {

    $socket = new TSocket('localhost', 9090);
    $transport = new TBufferedTransport($socket, 1024, 1024);
    $protocol = new TBinaryProtocol($transport);
    $client = new \hello\userExchangeClient($protocol);

    $transport->open();
    $client->ping();
    $u = new \hello\User();
    $u->user_id = 1;
    $u->firstname = 'John';
    $u->lastname = 'Smith';
    $u->sex = \hello\SexType::MALE;
    if ($client->add_user($u))
    {
        echo 'user added succesfully</br>'."\n";
    }
    
    var_dump($client->get_user(0));
    
    $client->clear_list();
    
    
    
    $u2 = new \hello\User();
    $client->add_user($u2);
    
} catch (\hello\InvalidValueException $e) {
    echo $e->error_msg."<br/>\n";
}

最后先运行python_server.py启动服务,然后执行php_client.php,一切正常的话会server端会看到如下数据

Starting the server...
ping()
Processing user John Smith
[User(user_id=1, description=None, firstname='John', lastname='Smith', sex=1, active=False)]
Clearing list
[User(user_id=1, description=None, firstname='John', lastname='Smith', sex=1, active=False)]
[]

客户端会看到

user added succesfully</br>
class hello\User#9 (6) {
  public $firstname =>
  string(4) "John"
  public $lastname =>
  string(5) "Smith"
  public $user_id =>
  int(1)
  public $sex =>
  int(1)
  public $active =>
  bool(false)
  public $description =>
  NULL
}
no firstname exception<br/>

这就表明数据已经正确的请求和响应了。

参考

标签: thrift

添加新评论