1

I have a fairly straightforward Thrift IDL (split into two files as shown):

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");
}

I am using a Python Tornado Server and a Java client, for which the code looks like:

Python server:

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 Client:

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");
    }
}

The client successfully connects to the server and the Python PointQueryHandler.getElevations function gets called. However, the problem is that the arguments to PointQueryHandler.getElevations are always the default arguments of an empty list and "undefined" string. Whatever data I pass from the Java client is not, for some reason, arriving at the server.

What could be going wrong?

(Thrift version: 0.9.2, Python 2.7.5, JDK 1.7.0_45, Platform: Windows 7 64-bit)

4

1 回答 1

0

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

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

于 2015-04-07T20:13:18.403 回答