Thrift java 基于阻塞IO的服务端多线程通信

首先引用此链接作为参考

此文章仅仅用于保存,以免遗忘。

1.配置环境

使用maven


  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.9</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.1</version>
    </dependency>
  </dependencies>

  <!--这里用于打包测试插件-->
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.yamm.ThriftServer.AdditionServer</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>assembly</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2.基本数据类型

3.1 数据类型

基本类型:

bool: 布尔值,true 或 false,对应 Java 的 Boolean

byte: 8 位有符号整数,对应 Java 的 byte

i16:16 位有符号整数,对应 Java 的 short

i32:32 位有符号整数,对应 Java 的 int

i64:64 位有符号整数,对应 Java 的 long

double:64 位浮点数,对应 Java 的 double

string:utf-8编码的字符串,对应 Java 的 String

结构体类型:

Struct: 定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean

容器类型:

list:对应 Java 的 ArrayList

set: 对应 Java 的 HashSet

map: 对应 Java 的 HashMap

异常类型:

    exception:对应 Java 的 Exception

服务类型:

    service:对应服务的类

枚举类型:

3.例子

  • 1.首先下载thrift 0.8.0.exe(如果是linux,那么需要去官网下载tar.gz版本编译安装)

  • 2.然后按照上面的格式写出自己的.thrift文件,我这里是test.thrift

namespace java com.yamm.ThriftServer  // defines the namespace   

typedef i32 int  //typedefs to get convenient names for your types  

service AdditionService {  // defines the service to add two numbers  
        int add(1:int n1, 2:int n2), //defines a method  
        string getFile(1:string n1,2:string n2),
}
  • 3.输入thrift.exe –gen java test.thrift就会在本地文件生成一个指定语言的客户端服务端文件。复制粘贴到java maven项目中.生成的文件内容较多–>我这里生成为AdditionService.java
    这里写图片描述

  • 4.然后创建一个方法,实现此接口类:

package com.yamm.ThriftServer;

import org.apache.thrift.TException;

public class AdditionServiceImp implements AdditionService.Iface{

    public int add(int n1, int n2) throws TException {
        System.out.println("调用成功!");
        while(true){
            if(n1<0)break;
        }
        return n1+n2;
    }
}

编写服务端

创建服务端类,这里服务端采用阻塞IO多线程方式:

package com.yamm.ThriftServer;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;

/*
 * Thrift经典的阻塞IO的多线程服务端
 */
public class AdditionServer {
    public static final int SERVER_PORT=7777;//端口号传输
    public static void main(String[] args) {
        System.out.println("start.....");
        try {
            TProcessor tprocessor = new AdditionService.Processor<AdditionService.Iface>(new AdditionServiceImp());
            //阻塞IO
            TServerSocket transport = new TServerSocket(SERVER_PORT);
            //多线程服务模型
            TThreadPoolServer.Args tnb_args = new TThreadPoolServer.Args(transport);//设置服务类型,TNonblocking是处理多线程比较好的
            tnb_args.processor(tprocessor);

//          tnb_args.transportFactory(new TFramedTransport.Factory());使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式,二进制传输

            //块传输协议,二进制协议
            tnb_args.protocolFactory(new TCompactProtocol.Factory());

            //start server
            TServer server = new TThreadPoolServer(tnb_args);
            System.out.println("start success port is : "+SERVER_PORT);
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }

    }
}

编写客户端

这里写图片描述

1.你需要将之前生成的代码再拷贝一份到客户端处,保持服务端客户端的接口类一致
2.创建客户端类,调用服务端方法

package com.yamm.Thrift_Client;

import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

public class AdditionClient {
    /*
     * 客户端
     * 
     * 定义地址     端口      连接超时时间
     * 
     */
    private static final String SERVER_IP = "localhost";
    private static final int PORT = 7777;
    private static final int TIME_OUT = 300000;
    public static void main(String[] args) {
        try{
            //获取会话
            TTransport  transport = new TSocket(SERVER_IP,PORT,TIME_OUT);
            //选择会话协议,注意要和服务端一致,不然无法通信
            TProtocol protocol = new TCompactProtocol(transport);
            AdditionService.Client client = new AdditionService.Client(protocol);
            //打开会话
            transport.open();

            //调用服务端方法,并返回
            System.out.println(client.add(2, 3));
            transport.close();
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

在这里我们会发现,客户端调用时会阻塞,因为我在方法里面放置了while(true)。然后我们多线程多运行几次客户端,会发现服务端依次执行,所以可以确认服务端为多线程提供服务,一个阻塞会开启新线程。

结果实验

这里写图片描述
这里写图片描述

可以看到,客户端调用被阻塞,服务端开启新线程给客户端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值