thrift文件

namespace java com.gxf.demo
namespace py tutorial typedef i32 int // We can use typedef to get pretty names for the types we are using
service MultiplicationService
{
int multiply(1:int n1, 2:int n2),
int add(1:int n1, 2:int n2),
} service SubService{
int sub(1:int n1, 2:int n2),
} struct User{
1: i32 id = 0,
2: required string name,
}
MultiplicationHandler.java
import org.apache.thrift.TException;

public class MultiplicationHandler implements MultiplicationService.Iface, SubService.Iface {

    @Override
public int multiply(int n1, int n2) throws TException {
System.out.println("Multiply(" + n1 + "," + n2 + ")");
return n1 * n2;
} @Override
public int add(int n1, int n2) throws TException {
System.out.println("add(" + n1 + "," + n2 + ")");
return n1 + n2;
} @Override
public int sub(int n1, int n2) throws TException {
System.out.println("sub(" + n1 + "," + n2 + ")");
return n1 - n2;
}
}
MultiplicationServer.java
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport; public class MultiplicationServer { public static MultiplicationHandler handler; public static MultiplicationService.Processor processor; public static void main(String [] args) {
try {
handler = new MultiplicationHandler();
processor = new MultiplicationService.Processor(handler);
Runnable simple = () -> simple(processor); new Thread(simple).start();
} catch (Exception x) {
x.printStackTrace();
}
} public static void simple(MultiplicationService.Processor processor) {
try {
TServerTransport serverTransport = new TServerSocket(9090);
TServer server = new TSimpleServer(new Args(serverTransport).processor(processor)); System.out.println("Starting the simple server...");
server.serve();
} catch (Exception e) {
e.printStackTrace();
}
}
}
MultiplicationClient.java
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport; public class MultiplicationClient { public static void main(String [] args) {
try {
TTransport transport;
transport = new TSocket("localhost", 9090);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
MultiplicationService.Client client = new MultiplicationService.Client(protocol);
SubService.Client subClient = new SubService.Client(protocol);
perform(client, subClient);
transport.close();
} catch (TException x) {
x.printStackTrace();
}
} private static void perform(MultiplicationService.Client client, SubService.Client subClient) throws TException
{
int product = client.multiply(3,5);
System.out.println("3 * 5 = " + product);
int sum = client.add(4, 6);
System.out.println("4 + 6 = " + sum);
}
}

跟进client代码

thrift主要把方法名,参数发送给服务方

跟进multiply(int n1, int n2)方法

public int multiply(int n1, int n2) throws org.apache.thrift.TException
{
send_multiply(n1, n2);
return recv_multiply();
}
send_multiply(n1, n2);跟进
public void send_multiply(int n1, int n2) throws org.apache.thrift.TException
{
multiply_args args = new multiply_args();
args.setN1(n1);
args.setN2(n2);
sendBase("multiply", args);
}

跟进sendBase

protected void sendBase(String methodName, TBase<?,?> args) throws TException {
sendBase(methodName, args, TMessageType.CALL);
}
protected void sendBaseOneway(String methodName, TBase<?,?> args) throws TException {
sendBase(methodName, args, TMessageType.ONEWAY);
}
private void sendBase(String methodName, TBase<?,?> args, byte type) throws TException {
oprot_.writeMessageBegin(new TMessage(methodName, type, ++seqid_));
args.write(oprot_);
oprot_.writeMessageEnd();
oprot_.getTransport().flush();
}

methodName被封装到Tmessage中,跟进 writeMessageBegin

public void writeMessageBegin(TMessage message) throws TException {
if (strictWrite_) {
int version = VERSION_1 | message.type;
writeI32(version);
writeString(message.name);
writeI32(message.seqid);
} else {
writeString(message.name);
writeByte(message.type);
writeI32(message.seqid);
}
}
public void writeI32(int i32) throws TException {
inoutTemp[0] = (byte)(0xff & (i32 >> 24));
inoutTemp[1] = (byte)(0xff & (i32 >> 16));
inoutTemp[2] = (byte)(0xff & (i32 >> 8));
inoutTemp[3] = (byte)(0xff & (i32));
trans_.write(inoutTemp, 0, 4);
}
public void write(byte[] buf, int off, int len) throws TTransportException {
if (outputStream_ == null) {
throw new TTransportException(TTransportException.NOT_OPEN, "Cannot write to null outputStream");
}
try {
outputStream_.write(buf, off, len);
} catch (IOException iox) {
throw new TTransportException(TTransportException.UNKNOWN, iox);
}
}

这里通过socket outputstream发送

private void sendBase(String methodName, TBase<?,?> args, byte type) throws TException {
oprot_.writeMessageBegin(new TMessage(methodName, type, ++seqid_));
args.write(oprot_);
oprot_.writeMessageEnd();
oprot_.getTransport().flush();
}

下面参数也是通过类似方法发送给服务端。发送完接收服务端发送的结果

public int recv_multiply() throws org.apache.thrift.TException
{
multiply_result result = new multiply_result();
receiveBase(result, "multiply");
if (result.isSetSuccess()) {
return result.success;
}
throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "multiply failed: unknown result");
}
protected void receiveBase(TBase<?,?> result, String methodName) throws TException {
TMessage msg = iprot_.readMessageBegin();
if (msg.type == TMessageType.EXCEPTION) {
TApplicationException x = new TApplicationException();
x.read(iprot_);
iprot_.readMessageEnd();
throw x;
}
if (msg.seqid != seqid_) {
throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID,
String.format("%s failed: out of sequence response: expected %d but got %d", methodName, seqid_, msg.seqid));
}
result.read(iprot_);
iprot_.readMessageEnd();
}
private static class multiply_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<multiply_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, multiply_result struct) throws org.apache.thrift.TException {
org.apache.thrift.protocol.TField schemeField;
iprot.readStructBegin();
while (true)
{
schemeField = iprot.readFieldBegin();
if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
break;
}
switch (schemeField.id) {
case 0: // SUCCESS
if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
struct.success = iprot.readI32();
struct.setSuccessIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
iprot.readFieldEnd();
}
iprot.readStructEnd(); // check for required fields of primitive type, which can't be checked in the validate method
struct.validate();
}

由于方法返回类型是int,这里读取结果主要判断是否成功,result值,以及解析结束。

后面在看下thrift服务端解析客户端请求代码

Thrift笔记(四)--Thrift client源码分析的更多相关文章

  1. 【原】Spark中Client源码分析(二)

    继续前一篇的内容.前一篇内容为: Spark中Client源码分析(一)http://www.cnblogs.com/yourarebest/p/5313006.html DriverClient中的 ...

  2. java 日志体系(四)log4j 源码分析

    java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...

  3. Java 集合系列(四)—— ListIterator 源码分析

    以脑图的形式来展示Java集合知识,让零碎知识点形成体系 Iterator 对比   Iterator(迭代器)是一种设计模式,是一个对象,用于遍历集合中的所有元素.  Iterator 包含四个方法 ...

  4. 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析

    今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...

  5. Spring Security(四) —— 核心过滤器源码分析

    摘要: 原创出处 https://www.cnkirito.moe/spring-security-4/ 「老徐」欢迎转载,保留摘要,谢谢! 4 过滤器详解 前面的部分,我们关注了Spring Sec ...

  6. Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析

    经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...

  7. Nginx学习笔记(五) 源码分析&内存模块&内存对齐

    Nginx源码分析&内存模块 今天总结了下C语言的内存分配问题,那么就看看Nginx的内存分配相关模型的具体实现.还有内存对齐的内容~~不懂的可以看看~~ src/os/unix/Ngx_al ...

  8. 并发编程(四)—— ThreadLocal源码分析及内存泄露预防

    今天我们一起探讨下ThreadLocal的实现原理和源码分析.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两 ...

  9. Nginx学习笔记(六) 源码分析&启动过程

    Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...

  10. Java并发编程笔记之Semaphore信号量源码分析

    JUC 中 Semaphore 的使用与原理分析,Semaphore 也是 Java 中的一个同步器,与 CountDownLatch 和 CycleBarrier 不同在于它内部的计数器是递增的,那 ...

随机推荐

  1. mybatis 学习笔记(三):mapper 代理开发 dao 层

    mybatis 学习笔记(三):mapper 代理开发 dao 层 优势 通过使用mapper 代理,我们可以不需要去编写具体的实现类(使用 getMapper() 方法自动生成),只需编写接口即可, ...

  2. NPOI.XWPF生成WORD,设置Table单元格的背景色

    tr.GetCell().SetColor("#fbd4b4");

  3. win10+anaconda环境下pyqt5+qt tools+eric6.18安装及汉化过程

    最近需要用python编写一个小程序的界面,选择了pyqt5+eric6的配套组合,安装过程中遇到一些坑,特此记录.参考书籍是电子工业出版社的<PyQt5快速开发与实战>. 因为我使用an ...

  4. javascript高级程序设计---js事件思维导图

    绘制思维软件与平时用的笔记,以及导出功能,这三个问题综合起来,于是我把思维导图分开画 1.js事件的基本概念 2.js事件的事件处理程序 3.js事件的事件对象

  5. Tomcat 连接数与线程池详解

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...

  6. 斐讯 N1 刷 Armbian 5.64

    前言 N1 天天链是斐讯出的一款挖矿产品,虽然已经翻车,但是本身硬件配置还是很不错的,晶晨 S905D 主控,蓝牙 4.1,双频 WiFi,2G + 8G,USB2.0,HDMI.而一个只要不到 80 ...

  7. ubuntu画面延迟问题解决

    新配的电脑,安装ubuntu16.04以后,出现画面延迟的问题,尤其浏览网页的时候画面十分卡顿.用free命令查看过可用内存6.多G,经过询问大概是显卡问题,然后在https://ubuntuforu ...

  8. AMD、CMD/AMD与CMD的区别

    http://blog.csdn.net/jackwen110200/article/details/52105493

  9. 江西理工大学南昌校区排名赛 F: 单身狗的骑马游戏

    题目描述 萌樱花是一只单身狗. 萌樱花今天在学姐那里做了一道题: 假设赛马场上有n只马儿,第i只马儿的起点在第i米的位置,这些马儿都会朝着同一个方向奔跑. 每只马儿的速度都不一样,而且大家都不知道这些 ...

  10. 启用和禁用TCPIP上的Netbios

    '设置传输值1是启用,设置2为禁用 On Error Resume Next strComputer = "." Set objWMIService = GetObject(&qu ...