接上篇,安装好之后,就开始编写IDL生成然后测试。

 

一、生成运行

参考 http://www.aboutyun.com/thread-8916-1-1.html 来个添加,查询。

namespace go  my.test.demo
namespace py  my.test.demo
 
struct Student{
 1: i32 sid, 
 2: string sname,
 3: bool ssex=0,
 4: i16 sage,
}
 
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
     
service ClassMember {        
    list<Student> List(1:i64 callTime),
    void Add(1: Student s),
    bool IsNameExist(1:i64 callTime, 2:string name),
}

通过以下命令来生成代码:

 thrift -r --gen go my.test.thrift 
 thrift -r --gen py my.test.thrift
├── client
├── client.go
├── gen-py
│   ├── __init__.py
│   ├── client.py
│   └── my
│       ├── __init__.py
│       ├── __init__.pyc
│       └── test
│           ├── __init__.py
│           ├── __init__.pyc
│           └── demo
│               ├── ClassMember-remote
│               ├── ClassMember.py
│               ├── ClassMember.pyc
│               ├── __init__.py
│               ├── __init__.pyc
│               ├── constants.py
│               ├── ttypes.py
│               └── ttypes.pyc
├── my
│   └── test
│       └── demo
│           ├── class_member-remote
│           │   └── class_member-remote.go
│           ├── classmember.go
│           ├── constants.go
│           └── ttypes.go
├── my.test.thrift
├── server
└── server.go

thrift帮忙生成代码部分:网络连接、数据序列化、RPC调用函数映射、数据发送等。

采用什么传输类型,采用什么服务类型,具体函数还要是自己写的。

参考:

类似Thrift的工具,还有Avro、protocol buffer,但相对于Thrift来讲,都没有Thrift支持全面和使用广泛。

1) thrift内部框架一瞥
  按照官方文档给出的整体框架,Thrift自下到上可以分为4层:
+-------------------------------------------+
| Server                                    |  -- 服务器进程调度
| (single-threaded, event-driven etc) |
+-------------------------------------------+
| Processor                                 |  -- RPC接口处理函数分发,IDL定义接口的实现将挂接到这里面
| (compiler generated)                      |
+-------------------------------------------+
| Protocol                                  |  -- 协议
| (JSON, compact etc)                       |
+-------------------------------------------+
| Transport                                 |  -- 网络传输
| (raw TCP, HTTP etc)                       |
+-------------------------------------------+

  Thrift实际上是实现了C/S模式,通过代码生成工具将接口定义文件生成服务器端和客户端代码(可以为不同语言),从而实现服务端和客户端跨语言的支持。用户在Thirft描述文件中声明自己的服务,这些服务经过编译后会生成相应语言的代码文件,然后用户实现服务(客户端调用服务,服务器端提服务)便可以了。其中protocol(协议层, 定义数据传输格式,可以为二进制或者XML等)和transport(传输层,定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等)被用作运行时库。

2)支持的数据传输格式、数据传输方式和服务模型
    (a)支持的传输格式
      TBinaryProtocol – 二进制格式.
      TCompactProtocol – 压缩格式
      TJSONProtocol – JSON格式
      TSimpleJSONProtocol –提供JSON只写协议, 生成的文件很容易通过脚本语言解析。
      TDebugProtocol – 使用易懂的可读的文本格式,以便于debug
    (b) 支持的数据传输方式
      TSocket -阻塞式socker
      TFramedTransport – 以frame为单位进行传输,非阻塞式服务中使用。
      TFileTransport – 以文件形式进行传输。
      TMemoryTransport – 将内存用于I/O. java实现时内部实际使用了简单的ByteArrayOutputStream。
      TZlibTransport – 使用zlib进行压缩, 与其他传输方式联合使用。当前无java实现。
    (c)支持的服务模型
      TSimpleServer – 简单的单线程服务模型,常用于测试
      TThreadPoolServer – 多线程服务模型,使用标准的阻塞式IO。
      TNonblockingServer – 多线程服务模型,使用非阻塞式IO(需使用TFramedTransport数据传输方式)

    3) Thrift IDL
  Thrift定义一套IDL(Interface Definition Language)用于描述接口,通常后缀名为.thrift,通过thrift程序把.thrift文件导出成各种不一样的代码的协议定义。IDL支持的类型可以参考这里:http://thrift.apache.org/docs/types

 

//client.go

package main

import (
    "./my/test/demo"
    "fmt"
    "git.apache.org/thrift.git/lib/go/thrift"
    "net"
    "os"
    "time"
)

const (
    HOST = "127.0.0.1"
    PORT = "10086"
)

func main() {
    startTime := currentTimeMillis()
    transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    transport, err := thrift.NewTSocket(net.JoinHostPort(HOST, PORT))
    if err != nil {
        fmt.Fprintln(os.Stderr, "error resolving address:", err)
        os.Exit(1)
    }

    useTransport := transportFactory.GetTransport(transport)
    client := demo.NewClassMemberClientFactory(useTransport, protocolFactory)
    if err := transport.Open(); err != nil {
        fmt.Fprintln(os.Stderr, "Error opening socket to "+HOST+":"+PORT, " ", err)
        os.Exit(1)
    }
    defer transport.Close()
    var i int32
    for i = 0; i < 5; i++ {
        var s demo.Student
        s.Sid = i
        s.Sname = fmt.Sprintf("name_%d", i)
        err := client.Add(&s)
        time.Sleep(time.Second * 3)
        fmt.Println("add", i, "student", err)
    }

    sList, err := client.List(currentTimeMillis())
    fmt.Println(err)
    for _, s := range sList {
        fmt.Println(s)
    }

    endTime := currentTimeMillis()
    fmt.Printf("calltime:%d-%d=%dms\n", endTime, startTime, (endTime - startTime))

}

func currentTimeMillis() int64 {
    return time.Now().UnixNano() / 1000000
}
View Code

相关文章:

  • 2021-12-30
  • 2021-08-21
  • 2021-12-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-10
猜你喜欢
  • 2022-12-23
  • 2021-08-09
  • 2022-12-23
  • 2021-09-21
  • 2021-05-26
  • 2022-12-23
  • 2022-02-23
相关资源
相似解决方案