【问题标题】:Apache Thrift: Communicating from Java Client to Python Tornado ServerApache Thrift:从 Java 客户端到 Python Tornado 服务器的通信
【发布时间】:2015-04-08 04:13:18
【问题描述】:

我有一个相当简单的 Thrift IDL(如图所示分成两个文件):

core.thrift

namespace cpp MyProduct.Core
namespace java com.mycompany.myproduct.core
namespace py myproduct.core

/**
 * Struct used to indicate a location referenced by geodetic coordinates.
 */ 
struct GeoPoint{
    /**
     * Latitude for this point
     */
    1: required double latitude;

    /**
     * Longitude for this point
     */
    2: required double longitude;

    /**
     * Elevation for this point
     */
    3: required double elevation;
}

processing.thrift

include "core.thrift"

namespace cpp MyProduct.Processing
namespace java com.mycompany.myproduct.processing
namespace py myproduct.processing

/**
 * MyProduct processing services
 */
service PointsQuery{
   /**
    * Returns elevation of a list of input (geodetic) points
    * The elevation attribute in input GeoPoints are ignored
    */
    list<double> getElevations(1: required list<core.GeoPoint> inputPoints = [], 2: required string layername = "undefined");
}

我正在使用 Python Tornado 服务器和 Java 客户端,其代码如下所示:

Python 服务器:

class PointQueryHandler(object):
    def __init__(self):
        self.log = {}

    def getElevations(self, inputPoints, layerName, callback=None):        
        elevation_list = []
        // ...implementation here to fill elevation list with doubles...
        if callback:
            callback(elevation_list)
        else:
            return elevation_list

def main():
    handler = PointQueryHandler()
    processor = PointsQuery.Processor(handler)
    factory = TBinaryProtocol.TBinaryProtocolFactory()
    server = TTornado.TTornadoServer(processor, factory)

    print "Starting the server..."
    server.bind(9090)
    server.start(1)
    ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

Java 客户端:

public class QueryPointsTest {
    public static void main(String [] args) {
        try {
            TTransport transport;

            transport = new TSocket("localhost", 9090);
            transport.open();

            TProtocol protocol = new TBinaryProtocol(transport);
            PointsQuery.Client client = new PointsQuery.Client(protocol);

            perform(client);

            transport.close();
        } catch (TTransportException x) {
            System.out.println("Unable to connect to service provider: " + "localhost" + 9090);
        } catch (TException err){
            System.out.println("Error when accessing remote service: ");
            err.printStackTrace();
        }
    }

    private static void perform(PointsQuery.Client client) throws TException
    {
        List<GeoPoint> pointList = new ArrayList<GeoPoint>();

        GeoPoint pt1 = new GeoPoint(74.53951, 34.36709, 0.0);
        GeoPoint pt2 = new GeoPoint(74.52242,34.35413, 0.0);
        GeoPoint pt3 = new GeoPoint(74.51398,34.41069, 0.0);
        GeoPoint pt4 = new GeoPoint(83, 39.36709, 0.0);

        pointList.add(pt1);
        pointList.add(pt2);
        pointList.add(pt3);
        pointList.add(pt4);

        List<Double> result = client.getElevations(pointList, "dummylayername");
        System.out.println("Done");
    }
}

客户端成功连接到服务器并调用 Python PointQueryHandler.getElevations 函数。但是,问题在于 PointQueryHandler.getElevations 的参数始终是空列表和“未定义”字符串的默认参数。出于某种原因,我从 Java 客户端传递的任何数据都不会到达服务器。

可能出了什么问题?

(Thrift 版本:0.9.2,Python 2.7.5,JDK 1.7.0_45,平台:Windows 7 64 位)

【问题讨论】:

  • 嗨。我知道你问这个已经有一段时间了,但是..我有同样的问题,想知道你是否有运气。如果你当然记得的话……

标签: thrift thrift-protocol


【解决方案1】:

默认参数存在一些已知问题,许多语言仍然根本没有实现这一点。因此,最让我困惑的是你总是得到默认值......?

建议将 args 转换为单个 struct 作为唯一参数传递。 struct 可能有默认值或使用 optional 字段,因为你喜欢它,因为它最符合你的用例。

【讨论】:

    猜你喜欢
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    相关资源
    最近更新 更多