thrift c_glib 库序列化学习

thrift c_glib 库序列化学习

最近在项目中需要在不同的语言(c, c++, java, python) 之间传递消息, 模式是 server(C++)需要向订阅者(observer) 发送更新.
大致的思路是server侦听某个端口, 然后observer 连接, 然后双方保持连接, 当有更新时, server 将消息下发给observer.
由于需要跨语言,所以我们需要一个序列化的库, 项目中之前引入的thrift 正好可以解决, 在需要支持的各种语言中, c语言由于本身没有面向对象, 所以特别单独学习了下thrift c_glib 的使用, 特此记录.

thrift c_glib

  1. thrift 是一个跨语言的RPC库, 自身带了很不错的网络框架,使用起来很简单, 基本上只需要很短的代码量就可以实现一个基于socket/HTTP的模式, 但是这个模式需要client端主动发起请求,然后server应答, 和我们的设计不太一致, 所以这里我只是把thrift 作为一个序列化的库来使用
  2. thrift 支持很多语言, 比如C++, Java, Python 等等, 但是它对C语言的支持需要glib 库, 并不是原生支持, 所以需要熟悉下glib库的用法

thrift c_glib 序列化例子

在安装好thrift 后, 我们需要编写消息体, 保存为 test.thrift
  1. struct test {
      1:boolean b1,
      2:i32 i2,
      3:string s3
    }

可以注意到这里的格式,非常类似c, 然后执行命令

  thrift -r --gen c_glib test.thrift

就会在gen-c_glib文件夹中生成对应的代码文件test_types.h, test_types.c
test_types.h 中定义了一些我们会用到的宏, 以及两个主要的结构体

  1. struct _test
    {
    ThriftStruct parent;
    /* public */
    gint32 i1;
    gboolean __isset_i1;
    gchar * s2;
    gboolean __isset_s2;
    };
    typedef struct _test test;
    struct _testClass
    {
    ThriftStructClass parent;
    };
    typedef struct _testClass testClass;
    GType test_get_type (void);
    #define TYPE_TEST (test_get_type())
    #define TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TEST, test))
    #define TEST_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), _TYPE_TEST, testClass))
    #define IS_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TEST))
    #define IS_TEST_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TYPE_TEST))
    #define TEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TEST, testClass))
编写序列化过程
  1. #include <string.h>
    #include <stdio.h>
    #include <glib-object.h>
    #include <thrift/c_glib/protocol/thrift_binary_protocol.h>
    #include <thrift/c_glib/transport/thrift_memory_buffer.h>
    #include "gen-c_glib/test_types.h"
    test* createTest(int num, const char* mesg)
    {
      test* t = g_object_new(TYPE_TEST, NULL);
      t->i1 = num;
      t->s2 = strdup(mesg);
      return t;
    }
    guchar* test2String(test* t, int* size) {
      ThriftTransport * transport = THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 1024, NULL));
      ThriftProtocol * protocol = THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));
      thrift_struct_write(THRIFT_STRUCT(t), protocol, NULL);
      guchar* buf = (guchar*) g_malloc0(1024);
      *size = thrift_memory_buffer_read(THRIFT_TRANSPORT(transport), buf, 1024, NULL);
      g_object_unref(transport);
      g_object_unref(protocol);
      return buf;
    }
    test* string2Test(const guchar* buf, int size) {
      ThriftTransport * transport = THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", size, NULL));
      ThriftProtocol * protocol = THRIFT_PROTOCOL(g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));
      thrift_memory_buffer_write(transport, (gpointer)buf, size, NULL);
      test* t = g_object_new(TYPE_TEST, NULL);
      thrift_struct_read(THRIFT_STRUCT(t), protocol, NULL);
      g_object_unref(transport);
      g_object_unref(protocol);
      return t;
    }
    int main() {
      test * t = createTest(1024, "hello");
      int size;
      guchar* buf = test2String(t, &size);
      g_object_unref(t);
      test * nt = string2Test(buf, size);
      g_free(buf);
      printf("%d %s\n", nt->i1, nt->s2);
      g_object_unref(nt);
      return 0;
    }

     

通过这样, 剩下的就只是server通过socket将转换成guchar的字符串 发送给客户端, 客户端在进行反序列化就可以得到信息了

转载于:https://www.cnblogs.com/gtsfreer/p/5112827.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java thrift开发通常需要以下步骤: 1. 安装thrift编译器:Thrift编译器可用于将thrift文件编译成Java源代码。 2. 编写thrift文件:thrift文件定义了数据类型和服务接口。可以使用thrift IDL语言编写thrift文件。 3. 编译thrift文件:使用thrift编译器将thrift文件编译成Java源代码。 4. 实现服务端:实现thrift生成的服务接口和处理程序。 5. 实现客户端:使用thrift生成的客户端代码调用服务。 下面是一个简单的Java thrift开发示例: 1. 编写thrift文件,定义一个服务接口和一个相关的数据类型: ``` namespace java com.example struct Person { 1: required string name 2: optional i32 age } service PersonService { void addPerson(1: Person person) Person getPerson(1: string name) } ``` 2. 使用thrift编译器将thrift文件编译成Java源代码: ``` thrift --gen java person.thrift ``` 3. 实现服务端: ``` public class PersonServiceImpl implements PersonService.Iface { @Override public void addPerson(Person person) throws TException { // 实现添加人员的逻辑 } @Override public Person getPerson(String name) throws TException { // 实现获取人员信息的逻辑 } } ``` 4. 实现客户端: ``` public class PersonServiceClient { public static void main(String[] args) throws TException { TTransport transport = new TSocket("localhost", 9090); transport.open(); TProtocol protocol = new TBinaryProtocol(transport); PersonService.Client client = new PersonService.Client(protocol); Person person = new Person(); person.setName("张三"); person.setAge(20); client.addPerson(person); Person result = client.getPerson("张三"); System.out.println(result.getName() + " " + result.getAge()); transport.close(); } } ``` 以上就是一个简单的Java thrift开发示例。当然,在实际开发中可能会涉及到更复杂的数据类型和服务接口,需要更多的代码和实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值