Thrift笔记(四)--Thrift client源码分析
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源码分析的更多相关文章
- 【原】Spark中Client源码分析(二)
继续前一篇的内容.前一篇内容为: Spark中Client源码分析(一)http://www.cnblogs.com/yourarebest/p/5313006.html DriverClient中的 ...
- java 日志体系(四)log4j 源码分析
java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...
- Java 集合系列(四)—— ListIterator 源码分析
以脑图的形式来展示Java集合知识,让零碎知识点形成体系 Iterator 对比 Iterator(迭代器)是一种设计模式,是一个对象,用于遍历集合中的所有元素. Iterator 包含四个方法 ...
- 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析
今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...
- Spring Security(四) —— 核心过滤器源码分析
摘要: 原创出处 https://www.cnkirito.moe/spring-security-4/ 「老徐」欢迎转载,保留摘要,谢谢! 4 过滤器详解 前面的部分,我们关注了Spring Sec ...
- Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析
经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...
- Nginx学习笔记(五) 源码分析&内存模块&内存对齐
Nginx源码分析&内存模块 今天总结了下C语言的内存分配问题,那么就看看Nginx的内存分配相关模型的具体实现.还有内存对齐的内容~~不懂的可以看看~~ src/os/unix/Ngx_al ...
- 并发编程(四)—— ThreadLocal源码分析及内存泄露预防
今天我们一起探讨下ThreadLocal的实现原理和源码分析.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两 ...
- Nginx学习笔记(六) 源码分析&启动过程
Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...
- Java并发编程笔记之Semaphore信号量源码分析
JUC 中 Semaphore 的使用与原理分析,Semaphore 也是 Java 中的一个同步器,与 CountDownLatch 和 CycleBarrier 不同在于它内部的计数器是递增的,那 ...
随机推荐
- Error creating bean with name 'dateSource' defined in file 错误信息
问题的原因: 在web项目中搭建SSM框架,启动Tomcat时出现错误信息 有配置文件:applicationContext-mybatis.xml (Spring配置) spring-servlet ...
- audio.play dom对象 JQ不支持play
*/ PausePlayVoice:function() { $("#spPauseAudio").click(function() { ...
- python xlwt 与 xlsxwriter 模块差别
Xlwt 模块有一个bug, 就是所用样式过多的话,之后的数据将使用不了样式,相反xlsxwriter 模块 不会有此问题. 用Xlwt模块的同学们,请务必转换用xlsxwriter模块 !!!!!! ...
- ACM自己之前寒假的基础总结
1.const double pi = acos(-1.0); acos:反余弦函数,需要#include<math.h>函数库,acos(-1.0)的意思就是求π的值 2.算法竞赛中,不 ...
- 将Eclipse的Java Project转换为Dynamic Web Project
在用Eclipse做JavaEE开发时经常遇到Web工程被识别为Java工程的问题,导致很多功能无法使用. 只需做以下操作便可解决该问题. 1.右击Java工程选择Properties 2.选择左边目 ...
- aoj0558
一.题意: 在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪.有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪.老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只 ...
- 转 .net 获取IP地址的三个方法的比较
获取用户IP地址的三个属性的区别(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR) 一.没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP ...
- .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 ...
- spark ALS 推荐算法参数说明
- Oracle 更改归档文件到ASM磁盘
01,配置磁盘路径