The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
chengxuyuan0917

go thrift 和 gprc 的问题

  •  
  •   chengxuyuan0917 · Sep 26, 2018 · 2773 views
    This topic created in 2812 days ago, the information mentioned may be changed or developed.

    最近在撸一个自己弄着玩的 api 网关, 对外是 http 的 restful 接口, 对内想用 gprc 和 thrift。

    gprc 和 thrift 都可以用生成的文件调用, 这样的话是如果服务端新增接口,那么调用端也要配合新增,就是纯 c/s 模式。 我想的是撸个网关,然后调用内部的服务,内部服务新增接口,不需要修改网关的代码,可以直接调用过去。

    比如,通过 consul 时候发现有新增的服务,调用时候可以省去新增服务的 client 端,网关这边 gprc 可以直接用 gprc.Invoke 调用,不是用 pb 文件的 XX 方法。 但是搞 thrift 时候找不到类似 gprc.Invoke 的方法,不知道怎么弄。 难道 thrift 必须两边都用上生成的文件才可以嘛?

    2 replies    2018-09-26 23:42:33 +08:00
    Raymon111111
        1
    Raymon111111  
       Sep 26, 2018
    thrift 得提供接口的包给调用方才行
    chengxuyuan0917
        2
    chengxuyuan0917  
    OP
       Sep 26, 2018
    @Raymon111111
    我知道怎么玩了,
    正常情况下是这样
    ```
    transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    transport, err := thrift.NewTSocket(net.JoinHostPort(HOST, PORT))
    useTransport,_ := transportFactory.GetTransport(transport)
    transport.Open()
    client := usersrv.NewUserInfoServiceClientFactory(useTransport, protocolFactory)


    然后 client.GetUserById(context.TODO(), id)
    ```


    参考了 gprc.Invoke,观察了下 thrift 的调用方法
    ```

    type UserInfoServiceClient struct {
    c thrift.TClient
    }

    // Deprecated: Use NewUserInfoService instead
    func NewUserInfoServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *UserInfoServiceClient {
    return &UserInfoServiceClient{
    c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)),
    }
    }```

    后来,直接自己构造里面的 thrift.TClient,
    stClient:=thrift.NewTStandardClient(protocolFactory.GetProtocol(useTransport), protocolFactory.GetProtocol(useTransport))

    var _args0 usersrv.UserInfoServiceGetUserByNameArgs
    _args0.Namea = "123"
    var _result1 usersrv.UserInfoServiceGetUserByIdResult
    stClient.Call(context.Background(),"getUserById", &_args0, &_result1);
    //if err = stClient.Call(context.Background(),"getUserById", &_args0, &_result1); err != nil {
    // fmt.Println(err)
    // return
    //}
    fmt.Println(_result1.GetSuccess())


    前提是知道入参跟出参是什么,不过自定义网关消息的结构是通用的。比如说现在是
    usersrv.UserInfoServiceGetUserByNameArgs,usersrv.UserInfoServiceGetUserByIdResult,
    以后通用起来可能就是 ApiGateway.MessageRequest , ApiGateway.MessageResponse 这样。只需要接口定义时候确定成通用的格式就好了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1113 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 18:09 · PVG 02:09 · LAX 11:09 · JFK 14:09
    ♥ Do have faith in what you're doing.