rpc调用 java_RPC调用的简单实现
RPC调用流程
流程描述:
1.服务调用者发送请求(interface#method#args)
2.客户端进行StringEncode编码
3.数据写到服务提供者
4.服务提供者接受请求
5.将接收的包进行StringDecode解码
6.服务提供方调用对应api
7.服务提供方响应方法调用结果
8.服务提供方将结果集进行StringEncode编码
9.服务提供方发送结果集包到服务调用者
10.服务调用者接受数据包
11.服务调用者将数据包进行StringDecode解码
12.服务调用者输出方法调用结果集
代码流程:
服务端接口:
package com.hx.zbhuang.netty.dubboCall;
/**
* 远程服务接口
*/
public interface HelloService {
String hello(String mes);
String say(String msg);
}
服务端接口实现类:
package com.hx.zbhuang.netty.dubboCall;
/**
* 远程服务实现类
*/
public class HelloServiceImpl implements HelloService {
@Override
public String hello(String msg) {
if(msg!=null) {
return "hello 豆腐蛋,i accept you msg:["+msg+"]";
} else {
return "hello 豆腐蛋,i accept you msg";
}
}
@Override
public String say(String msg) {
return "hello 豆腐蛋" + "==msg:"+msg;
}
}
服务端初始化:
package com.hx.zbhuang.netty.dubboCall;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
/**
* 服务端初始化
*/
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = null;
EventLoopGroup workerGroup = null;
try {
workerGroup = new NioEventLoopGroup();
bossGroup = new NioEventLoopGroup(1);
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
// 服务端拦水坝处理
pipeline.addLast(new NettyServerHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(7766).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
服务端数据处理handler
package com.hx.zbhuang.netty.dubboCall;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.lang.reflect.Method;
public class NettyServerHandler extends SimpleChannelInboundHandler {
/**
* 读取客户端需要调用的方法进行处理返回结果集
* @param ctx
* @param msg
* @throws Exception
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("msg="+msg);
String methodName = msg.toString().split("#")[1];
Method[] methods = HelloService.class.getMethods();
for (Method method:methods) {
if(method.getName().equals(methodName)) {
Object obj = method.invoke(new HelloServiceImpl(),msg.toString().substring(msg.toString().lastIndexOf("#")+1));
ctx.writeAndFlush(obj.toString());
}
}
}
/**
* 异常处理
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
客户端接口调用初始化
package com.hx.zbhuang.netty.dubboCall;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NettyClient {
//线程池管理客户端请求
private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static NettyClientHandler client;
/**
* 返回服务端接口方法调用结果集
* @param serviceClass
* @param interfaceName
* @return
*/
Object getBean(final Class> serviceClass, final String interfaceName){
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class>[]{serviceClass},(proxy,method,args) -> {
if (client ==null) {
initClient();
}
client.setPara(interfaceName+"#"+method.getName()+"#"+args[0]);
Object obj = executor.submit(client).get();
return obj;
});
}
/**
* 客户端初始化
*/
private static void initClient() {
client = new NettyClientHandler();
NioEventLoopGroup group =null;
try {
group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline=socketChannel.pipeline();
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
// 客户端拦水坝处理
pipeline.addLast(client);
}
});
bootstrap.connect("127.0.0.1",7766).sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
客户端数据处理handler
package com.hx.zbhuang.netty.dubboCall;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.concurrent.Callable;
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {
// channelHandler上下文
private ChannelHandlerContext context;
// 远程服务获取方法调用结果
private String result;
// 接口名#方法名#参数
private String para;
/**
* 将请求写到服务端
* @return
* @throws Exception
*/
@Override
public synchronized Object call() throws Exception {
context.writeAndFlush(para);
wait();
return result;
}
/**
* 获取上下文信息
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
context = ctx;
}
/**
* 获取服务端调用结果
* @param ctx
* @param msg
* @throws Exception
*/
@Override
public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
result = msg.toString();
notify();
}
/**
* 异常处理
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
void setPara(String para) {
this.para = para;
}
}
模拟接口调用:
package com.hx.zbhuang.netty.dubboCall;
public class ClientBootstrap {
// 暴露的接口名
public static final String interfaceName = "HelloService";
public static void main(String[] args) throws InterruptedException {
NettyClient customer = new NettyClient();
// 调用远程服务接口
HelloService service = (HelloService)customer.getBean(HelloService.class, interfaceName);
String msg = service.say("来打王者");
System.out.println("调用结果"+ msg);
}
}
客户端远程调用服务端接口响应:
本文地址:https://blog.csdn.net/qq_33554285/article/details/110457528
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
rpc调用 java_RPC调用的简单实现相关推荐
- RabbitMQ学习系列(五): RPC 远程过程调用
前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用.不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/ca ...
- 130、RPC远程过程调用
RPC简介 1. 什么是RPC 远程过程调用(英语:Remote Procedure Call,缩写为 RPC,也叫远程程序调用)是一个计算机通信协议.该协议允许运行于一台计算机的程序调用另一台计算机 ...
- rpc接口并发调用实例
问题背景 需要根据id通过rpc调用查询具体信息,因为没有提供批量查询的接口,所以做法是挨个遍历查询,那意味着: 如果有100个id,就需要顺序进行100次rpc调用,假设每次rpc接口的调用时间是5 ...
- RPC 远程过程调用
RPC简介 RPC,英文全称: Remote Procedure Call. 中文名: 远程过程调用,是一个计算机通讯协议.借助RPC可以像调用本地服务一样地调用远程服务.比如两台服务器订单服务器和商 ...
- java调c的接口_Java调用C接口的简单示例
Java调用C接口的简单示例 正好需要用到Java调用dll里的C接口,想到自己做个简单的例子.我们可能需要自己生成dll文件,下边介绍一下,详细的步骤.主要参考https://blog.csdn.n ...
- 前端基础12:递归调用,快速排序和简单DOM元素操作
递归调用 递归调用,方法自己调用自己(重复执行方法中的逻辑) 1.在方法内部调用自己的方法写在return 2.设置边界条件,让递归调用停下来 function fn(n) {if(n == 1){r ...
- C# 委托的三种调用示例(同步调用 异步调用 异步回调)
首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b); public clas ...
- C++代码封装成dll供C#中调用、调用dll无可用源
C#工程不可以直接调用C++的头文件和Lib库等 所以在程序中C#需要调用的现象,先将C++的东西封装成动态链接库,再调用 若调用dll时显示:无可用源调用,说明导入的DLL路径不对. 静态库和动态库 ...
- java调用怎么调用方法区_Java中的方法调用有多昂贵
java调用怎么调用方法区 我们都去过那儿. 在查看设计不良的代码的同时,听听作者对人们永远不应该牺牲性能而不是设计的解释. 而且,您不能说服作者摆脱其500行方法,因为链接方法调用会破坏性能. 好吧 ...
- php教程调用数据库,PHP数据库调用类调用实例,php数据库调用实例_PHP教程
PHP数据库调用类调用实例,php数据库调用实例 config("dns=aaa;uid=sa;pwd=sa;dbname=test"); //3.选择数据库 $dbname = ...
最新文章
- 从创业公司到AI巨头 出门问问如何定义下一代人机交互?
- spring3.0注解
- MDNS的漏洞报告——mdns的最大问题是允许广域网的mdns单播查询,这会暴露设备信息,或者被利用用于dns放大攻击...
- 《Total Commander:万能文件管理器》——第2.3节.下载与安装
- python联盟是什么意思_Python 与 英雄联盟(1)
- 牛客 - 弦(卡特兰数)
- python引用传递产生的问题_理解Python中传递值和引用时出现问题
- java日志——基本日志+高级日志
- MATLAB入门(二)
- ZOJ 1295——Reverse Text
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别、不可重复读与幻读的区别
- TCP洪水攻击(SYN Flood)的诊断和处理
- MyBatis查询返回Map类型数据
- 我讨厌电脑!一个系统管理员的自白
- Delphi动态事件深入分析
- 数据挖掘导论——可视化分析实验
- 彩虹六号按键精灵挂机脚本制作教程
- day13、1 - 抓包--科来软件使用
- 文件管理系统:5款优秀的文档管理系统
- 研究云计算中调度算法遇到的相关概念