Thrift C and Golang language implementations and mutual invocation methods

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Thrift's go and C language implementations

Thrift 是Facebook为了解决各系统间大数据量的传输通信以及系统之间语言环境不同而设计的一种传输框架。目前来看常用的主流语言Thrift都已经很好地支持,并且github上已经有很多实现,除了C语言之外。Thrift传输的程序的静态数据,即数据的数据结构必须事前固定。Thrift原理就不介绍了,理论性东西网上很多,并且都是雷同的。下面通过实例介绍Thrift 接口在Go与C语言下的实现,以及如何在C语言中调用Go所编写的Thrift客户端。

1. Thrift File Preparation

#example.thrift    namespace go thrift.rpc    struct Response {    1: required string data;    }service RpcService {    Response Test(1:string input)}

2. Thrift code for Go and C

thrift -r --gen go example.thriftthrift -r --gen c_glib example.thrift

At this point in the directory will appear gen-go and Gen-c_gib two folders, which contains thrift automatically generated data structure body and function declaration.

3. Server-side implementation of Go

/* server.go */package mainimport (    "./gen-go/thrift/rpc"    "git.apache.org/thrift.git/lib/go/thrift"    "log"    "os")const (    NetworkAddr = "localhost:9090")type RpcServiceImpl struct {}func (this *RpcServiceImpl) Test(input string) (r *rpc.Response, err error) {    //函数具体实现    return}func main() {    transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()    serverTransport, err := thrift.NewTServerSocket(NetworkAddr)    if err != nil {        log.Println("Error!", err)        os.Exit(1)    }    handler := &RpcServiceImpl{}    processor := rpc.NewRpcServiceProcessor(handler)    log.Println("thrift server in", NetworkAddr)    server.Serve()}

4. The client implementation of Go

/* client.go */import (    "./gen-go/thrift/rpc"    "fmt"    "git.apache.org/thrift.git/lib/go/thrift"    "net"    "os")func main(){ip := "127.0.0.1"port := "9090"input :=""  transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()    tSocket, err := thrift.NewTSocket(net.JoinHostPort(ip, port))    if err != nil {        fmt.Fprintln(os.Stderr, "Error resolving address, ", err)        os.Exit(1)    }    tTransport, _ := transportFactory.GetTransport(tSocket)    client := rpc.NewRpcServiceClientFactory(tTransport, protocolFactory)    if err := tTransport.Open(); err != nil {        fmt.Fprintln(os.Stderr, (fmt.Errorf("Error opening socket to %s:%s : %v", ip, port, err)))        os.Exit(1)    }    defer tTransport.Close()    resp, _ := client.Test(input)}

C's Client implementation

The client implementation of

C is currently not available on GitHub, and thrift seems to have been supported recently. Thrift is an object-oriented framework, C language object-oriented implementation must rely on the GObject library, so here side in the implementation of the process need to note that the thrift file defined in the struct, the other can be directly instantiated to the object, in C must use the G_object_ The new function is initialized, or strcut will not be implemented. There will always be a parameter that cannot be found on the receiving server side of the corresponding structure.

/* client.c */#include <stdio.h> #include <glib-object.h> #include <string.h> #include <thrift/c_ Glib/protocol/thrift_binary_protocol.h> #include <thrift/c_glib/transport/thrift_framed_transport.h>#     Include <thrift/c_glib/transport/thrift_socket.h> #include "gen-c_glib/rpc_service.h" struct thrift_if{   Thriftsocket *socket;   Thrifttransport *transport;   Thriftprotocol *protocol; Rpcserviceif *client;}; void If_open (struct thrift_if* if_instance, Gchar *hostname, Gint32 port, Gerror **error) {#if (!                            Glib_check_version (2, 0)) G_type_init (); #endif if_instance->socket = G_object_new (Thrift_type_socket, "hostname", hostname, "Port", Port, NULL   ); If_instance->transport = G_object_new (Thrift_type_framed_transport, "Transport", If_instanc    E->socket, NULL); If_instance->protocol = G_object_new (Thrift_type_binary_protocol, "Transport", If_instance->transport,    NULL);    Thrift_transport_open (If_instance->transport, error);    if (!error) {return; } if_instance->client = G_object_new (type_rpc_service_client, "Input_protocol", If_instanc E->protocol, "Output_protocol", If_instance->protocol, NULL);}     void If_close (struct thrift_if *if_instance, Gerror **error) {g_clear_error (error);    Thrift_transport_close (If_instance->transport, NULL);    G_object_unref (if_instance->client);    G_object_unref (If_instance->protocol);    G_object_unref (If_instance->transport); G_object_unref (If_instance->socket);}    int main () {Gchar *hostname = "127.0.0.1";    Gint32 port = 9090;    Gchar *input = "" Struct thrift_if if_instance;     Gerror *error = NULL; If_open (&if_instance, hostname, port, &error);    Gchar *data;    Response *res;    Res = G_object_new (type_response,null); if (!error && rpc_service_if_test (if_instance.client,&res,input,&error)) {G_object_get (Res    , "Data", &data, NULL); } if_close (&if_instance, &error); return 0;}
编译:gcc  client.c gen-c_glib/rpc_service.c gen-c_glib/sven_types.c -o client -lthrift_c_glib -lgobject-2.0

5. Call the Go client in C code

Because the client-side compilation of C relies on the thrift_c_glib and GObject dynamic libraries, and some of the Linux system libraries are referenced in the Thrift_c_glib dynamic library, the dependency of the dynamic library is complex, which is not conducive to the stable, non-dependent deployment of the client.
You can use go to write the client, and then compile the. So file for the C program to call. Because go uses static source code to compile the way, can migrate to each server without dependency, need to pay attention to the transformation between C and go basic data structure in the process. The code is basically the same as the go client implementation, except that go and C directly do not allow the transfer of structs, so only basic data types can be passed

 /*client.go */Package Mainimport ("./gen-go/thrift/rpc" "C" "FMT" "git.apache.org/thrift.git/lib/ Go/thrift "" "Net" "OS")/*!!! Be sure to write "//export Test", this is not a comment!!! *///export Testfunc Test (Input string, IP string, port string) *c.char {transportfactory: = thrift. Newtframedtransportfactory (Thrift. Newttransportfactory ()) Protocolfactory: = Thrift. Newtbinaryprotocolfactorydefault () Tsocket, err: = Thrift. Newtsocket (NET. Joinhostport (IP, port)) if err! = Nil {fmt. Fprintln (OS. Stderr, "Error Resolving Address,", err) OS. Exit (1)} Ttransport, _: = Transportfactory.gettransport (tsocket) Client: = RPC. Newrpcserviceclientfactory (Ttransport, protocolfactory) If err: = Ttransport.open (); Err! = Nil {fmt. Fprintln (OS. Stderr, (FMT. Errorf ("Error opening socket to%s:%s:%v", IP, port, err)) OS. Exit (1)} defer Ttransport.close () resp, _: = client. Test (input) return c.cstring (resp. Data)}  

Compiled to a dynamic library, execute the following command to generate Libclient.h and libclient.so two files.

go build -buildmode=c-shared -o libclient.so client.go

The C language calls the go-generated dynamic library:

#include <stdio.h>#include "libclient.h"int main(){    GoString input = {(char*)"test", 4};    GoString ip = {(char*)"127.0.0.1", 9};    GoString port = {(char*)"9090", 4};    char *res = NULL;    res = Test(input, ip, port);    if (res != NULL)    {        printf("%s\n", res);    }    return 0;}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.