Apache Thrift学习入门之代码演示

本文最后更新于2018年6月25日,已超过 1 年没有更新,如果文章内容失效,还请反馈给我,谢谢!

=Start=

缘由:

之前在学习Apache Thrift的过程中记录了一篇文章,但没有包含代码演示,这次加上参考文章中验证过可用的Java代码,同时补上其它语言(这里是Python)的client端调用代码。

正文:

参考解答:

1. 先创建 Thrift(IDL) 文件,同时生成代码

namespace java com.ixyzero.learn.thrift //这一行里面的java关键字必不可少,否则生成Java代码的时候可能会报错

service HelloWorldService {
  string sayHello(1:string username)
}

我遇到过的一些报错信息:

(last token was 'service')
syntax error
Parser error during include pass.

&

#生成Java版本,会在当前目录下生成 gen-java 子目录
thrift -r --gen java helloWorld.thrift

#生成Python版本,会在当前目录下生成 gen-py 子目录
thrift -r --gen py helloWorld.thrift

2. 实现接口 Iface

package com.ixyzero.learn.thrift;

import org.apache.thrift.TException;

/**
 * Created by ixyzero.com on 2018/5/30.
 */
public class HelloWorldImpl implements HelloWorldService.Iface {

    public HelloWorldImpl() {
    }

    @Override
    public String sayHello(String username) throws TException {
        long time1 = System.currentTimeMillis();
        System.out.println(time1);
        try {
            Thread.sleep(1000L * 1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(System.currentTimeMillis());
        System.out.println(System.currentTimeMillis() - time1);
        return "Hi, '" + username + "' welcome to thrift world";
    }
}

3. 编写 Server端 代码

# Java 版本

package com.ixyzero.learn.thrift;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;

public class HelloServerDemo {
    public static final int SERVER_PORT = 8090;

    public void startServer() {
        try {
            System.out.println("HelloWorld TSimpleServer start ....");

            TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldImpl());

            // 简单的单线程服务模型,一般用于测试
            TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
            TServer.Args tArgs = new TServer.Args(serverTransport);
            tArgs.processor(tprocessor);
            tArgs.protocolFactory(new TBinaryProtocol.Factory());
            // tArgs.protocolFactory(new TCompactProtocol.Factory());
            // tArgs.protocolFactory(new TJSONProtocol.Factory());
            TServer server = new TSimpleServer(tArgs);
            server.serve();

        } catch (Exception e) {
            System.out.println("Server start error!!!");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        HelloServerDemo server = new HelloServerDemo();
        server.startServer();
    }
}

# Python版本

#!/usr/bin/env python
# coding=utf-8

import socket
import sys

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

from helloWorld import HelloWorldService
from helloWorld.ttypes import *

class HelloWorldServiceHandler:
    def sayHello(self, msg):
        ret = "Received: " + msg
        print ret
        return ret

handler = HelloWorldServiceHandler()
processor = HelloWorldService.Processor(handler)
transport = TSocket.TServerSocket("localhost", 9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

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

print "Starting thrift server in python..."
server.serve()
print "done!"

4. 编写 Client端 代码

# Java版本

package com.ixyzero.learn.thrift;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

public class HelloClientDemo {

    public static final String SERVER_IP = "localhost";
    public static final int SERVER_PORT = 8090;
    public static final int TIMEOUT = 30000;

    /**
     * @param userName
     */
    public void startClient(String userName) {
        TTransport transport = null;
        try {
            transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
            // 协议要和服务端一致
            TProtocol protocol = new TBinaryProtocol(transport);
            // TProtocol protocol = new TCompactProtocol(transport);
            // TProtocol protocol = new TJSONProtocol(transport);
            HelloWorldService.Client client = new HelloWorldService.Client(protocol);
            transport.open();
            long time1 = System.currentTimeMillis();
            String result = client.sayHello(userName);
            long time2 = System.currentTimeMillis();
            System.out.print("spend ");
            System.out.print(time2 - time1);
            System.out.println(" ms to call method client.sayHello()");
            System.out.println("Thrift client result =: " + result);
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }
    }

    public static void main(String[] args) {
        HelloClientDemo client = new HelloClientDemo();
        client.startClient("china");
    }
}

# Python版本

#!/usr/bin/env python
# coding=utf-8

import sys

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

from helloWorld import HelloWorldService

try:
    socket = TSocket.TSocket('localhost', 8090) # 8090调用的Java,9090调用的Python
    socket.setTimeout(2000)
    # transport = TTransport.TFramedTransport(socket) #用这个会出现time out异常
    transport = TTransport.TBufferedTransport(socket)  #用这个就没问题,因为和Server端一致
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = HelloWorldService.Client(protocol)
    transport.open()

    msg = client.sayHello("hello")
    print msg
    msg = client.sayHello("nihao")
    print msg

    transport.close()

except:
    print "{0}".format(traceback.format_exc())

Server端 和 Client端 的 transport 要一致,protocol 也要一致,否则会出现一些问题,比如 time out 。

 

参考链接:
=END=

声明: 除非注明,ixyzero.com文章均为原创,转载请以链接形式标明本文地址,谢谢!
https://ixyzero.com/blog/archives/3999.html

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注