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. C# Winform下一个热插拔的MIS/MRP/ERP框架12(数据处理基类)

    作为ERP等数据应用程序,数据库的处理是重中之重. 在框架中,我封装了一个数据库的基类,在每个模组启动或窗体启动过程中,实例化一个基类即可调用CRUD操作(create 添加read读取 update ...

  2. OOP3(继承中的类作用域/构造函数与拷贝控制/继承与容器)

    当存在继承关系时,派生类的作用域嵌套在其基类的作用域之内.如果一个名字在派生类的作用域内无法正确解析,则编译器将继续在外层的基类作用域中寻找该名字的定义 在编译时进行名字查找: 一个对象.引用或指针的 ...

  3. leecode刷题(7)-- 加一

    leecode刷题(7)-- 加一 加一 描述: 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 ...

  4. 《条目十六》如何将vector和string的数据传给遗留的API

    <条目十六>如何将vector和string的数据传给遗留的API 优秀的代码是可以延续的,所以并非所有的代码都是重构的,而且有时候重构会对整个系统影响较大,投入巨大,得不偿失.然而,也不 ...

  5. win7关闭关机时的自动终止的功能

    gpedit.msc->计算器配置->管理模板->系统->关机选项->启用 参考: http://www.xitongcheng.com/jiaocheng/win7_a ...

  6. js 原生JS实现轮播图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. struts2学习笔记(六)—— 拦截器

    一.拦截器概述 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些操作.拦截器是AOP的一种实现策略. 在We ...

  8. hexo 博客

    梦飞扬~ 个人网站:Mauger`s Blog 博客园 标签 新随笔 随笔 管理 Github 随笔 - 61  文章 - 1  评论 - 0 使用Node.js+Hexo+Github搭建个人博客 ...

  9. 高精度的N进制转换模板(转K神)

    /* 高精度进制转换 把oldBase 进制的数转化为newBase 进制的数输出. 调用方法,输入str, oldBase newBase. change(); solve(); output(); ...

  10. 使用PHP并发执行任务–curl_multi应用

    使用PHP并发执行任务–curl_multi应用 原网址:http://lampblog.org/category/phpdev