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. Error creating bean with name 'dateSource' defined in file 错误信息

    问题的原因: 在web项目中搭建SSM框架,启动Tomcat时出现错误信息 有配置文件:applicationContext-mybatis.xml (Spring配置) spring-servlet ...

  2. audio.play dom对象 JQ不支持play

    */        PausePlayVoice:function() {            $("#spPauseAudio").click(function() {     ...

  3. python xlwt 与 xlsxwriter 模块差别

    Xlwt 模块有一个bug, 就是所用样式过多的话,之后的数据将使用不了样式,相反xlsxwriter 模块 不会有此问题. 用Xlwt模块的同学们,请务必转换用xlsxwriter模块 !!!!!! ...

  4. ACM自己之前寒假的基础总结

    1.const double pi = acos(-1.0); acos:反余弦函数,需要#include<math.h>函数库,acos(-1.0)的意思就是求π的值 2.算法竞赛中,不 ...

  5. 将Eclipse的Java Project转换为Dynamic Web Project

    在用Eclipse做JavaEE开发时经常遇到Web工程被识别为Java工程的问题,导致很多功能无法使用. 只需做以下操作便可解决该问题. 1.右击Java工程选择Properties 2.选择左边目 ...

  6. aoj0558

    一.题意: 在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪.有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只 ...

  7. 转 .net 获取IP地址的三个方法的比较

    获取用户IP地址的三个属性的区别(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)   一.没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP    ...

  8. .sort(function(a,b){return a-b});

    var points = [40,100,1,5,25,10]; var b= points.sort(function(a,b){return a-b}); console.log(b); 那个fu ...

  9. spark ALS 推荐算法参数说明

  10. Oracle 更改归档文件到ASM磁盘

    01,配置磁盘路径