netty实现远程调用RPC功能
netty实现远程调用RPC功能
PRC的功能一句话说白了,就是远程调用其他电脑的api
依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.31.Final</version>
</dependency>
服务端功能模块编写
项目结构

ClassInfo
package test; import java.io.Serializable; public class ClassInfo implements Serializable { private static final long serialVersionUID = -8970942815543515064L; private String className;//类名
private String methodName;//函数名称
private Class<?>[] types;//参数类型
private Object[] objects;//参数列表
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Class<?>[] getTypes() {
return types;
}
public void setTypes(Class<?>[] types) {
this.types = types;
}
public Object[] getObjects() {
return objects;
}
public void setObjects(Object[] objects) {
this.objects = objects;
}
}
InvokerHandler
package test; import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; public class InvokerHandler extends ChannelInboundHandlerAdapter {
public static ConcurrentHashMap<String, Object> classMap = new ConcurrentHashMap<String,Object>();
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ClassInfo classInfo = (ClassInfo)msg;
Object claszz = null;
if(!classMap.containsKey(classInfo.getClassName())){
try {
claszz = Class.forName(classInfo.getClassName()).getDeclaredConstructor().newInstance();
classMap.put(classInfo.getClassName(), claszz);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
}else {
claszz = classMap.get(classInfo.getClassName());
}
Method method = claszz.getClass().getMethod(classInfo.getMethodName(), classInfo.getTypes());
Object result = method.invoke(claszz, classInfo.getObjects());
System.out.println("服务器接受客户端的数据" + result);
ctx.write("SeverSendData");
ctx.flush();
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} }
RPCServer
package test; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder; public class RPCServer {
private int port; public RPCServer(int port) {
this.port = port;
} public void start() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup(); try {
ServerBootstrap serverBootstrap =
new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class).localAddress(port)
.childHandler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast("encoder", new ObjectEncoder());
pipeline.addLast("decoder",
new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
pipeline.addLast(new InvokerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture future = serverBootstrap.bind(port).sync();
System.out.println("Server start listen at " + port);
future.channel().closeFuture().sync();
} catch (Exception e) {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
} public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new RPCServer(port).start();
}
}
SeverClass
package test; public class SeverClass implements SeverInterface { @Override
public String fn(String data) {
return data;
} }
SeverInterface
package test; public interface SeverInterface {
String fn(String data);
}
客户端功能模块编写
目录结构

App
package test; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder; public class App
{
public static void main(String [] args) throws Throwable{ ClassInfo classInfo = new ClassInfo();
classInfo.setClassName("test.SeverClass");
classInfo.setMethodName("fn");
classInfo.setObjects(new Object[]{"ClientSendData"});
classInfo.setTypes(new Class[]{String.class}); ResultHandler resultHandler = new ResultHandler();
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
pipeline.addLast("encoder", new ObjectEncoder());
pipeline.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
pipeline.addLast("handler",resultHandler);
}
}); ChannelFuture future = b.connect("localhost", 8080).sync();
future.channel().writeAndFlush(classInfo).sync();
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
} System.out.println("调用服务器数据返回回来的数据:" + resultHandler.getResponse());
}
}
ResultHandler
package test; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; public class ResultHandler extends ChannelInboundHandlerAdapter { private Object response; public Object getResponse() {
return response;
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
response = msg;
System.out.println("调用服务器数据返回回来的数据:" + response);
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("client exception is general");
}
}
netty实现远程调用RPC功能的更多相关文章
- Atitit.分布式远程调用 rpc rmi CORBA的关系
Atitit.分布式远程调用 rpc rmi CORBA的关系 1. 远程调用(包括rpc,rmi,rest)1 2. 分布式调用大体上就分为两类,RPC式的,REST式的1 3. RPC(远程 ...
- java 远程调用 RPC
1. 概念 RPC,全称为Remote Procedure Call,即远程过程调用,它是一个计算机通信协议.它允许像调用本地服务一样调用远程服务.它可以有不同的实现方式.如RMI(远程方法调用).H ...
- 远程调用RPC
一.简介 RPC,就是Remote Procedure Call的简称呀,翻译成中文就是远程过程调用. 本地调用,就好比你现在在家里,你要想洗碗,那你直接把碗放进洗碗机,打开洗碗机开关就可以洗了.这就 ...
- (转)RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...
- RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇 ...
- RabbitMQ 适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...
- RabbitMQ入门学习系列(七) 远程调用RPC
快速阅读 生产者和消费者启动以后,都有一个接收事件,消费者是接收事件是处理调用方法以后等待生产者的返回,生产者的接收事件是处理接收生产者发送的消息,进行处理.消费者发送的时候要在回调队列中加入一个标识 ...
- go程序添加远程调用tcpdump功能
最近开发的telemetry采集系统上线了.听起来高大上,简单来说就是一个grpc/udp服务端,用户的机器(路由器.交换机)将它们的各种统计数据上报采集.整理后交后端的各类AI分析系统分析.目前华为 ...
- goroute应用-模拟远程调用RPC
go语言简单模拟RPC,详见个人新博客:blog.dlgde.cn 代码如下: package main import ( "errors" "fmt" &qu ...
随机推荐
- 三十八 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装
elasticsearch(搜索引擎)介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticse ...
- idea结合git使用
1.下载安装好git.exe2. 2.安装好以后在cmd输入git 3.在idea配置git环境 4.托管项目到码云 5.登录码云官网,地址就是你在码云注册的账号和密码
- cin关闭流同步加速
习惯了用cin 很多人会说cin的速度比scanf慢很多, 其实不然. cin慢的原因主要在于默认cin与stdin总是保持同步, 这一步是消耗时间大户. 只需要加上std::iOS::sync_wi ...
- 【转】安装OS X虚拟机错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123
新建一个虚拟机, 选择客户机操作系统为Apple MacOS X 10.10, 其余参数可以默认. 注意建好之后不要急着打开客户机, 因为直接打开你会发现新建的客户机将会无法启动. 仔细阅读Mac O ...
- 重读tcp-ip详解三卷:1
应用层 Http.Telnet.FTP和e-mail等 负责把数据传输到传输层或接收从传输层返回的数据传输层 TCP和UDP 主要为两台主机上的应用程序提供端到端的通信,TCP为两台主机提供高可靠性的 ...
- c++ 基础知识 0001 const 知识1
1. C++ const用法 尽可能使用const 2. C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的.如果在编程中确实有某个值保持不变,就 ...
- SVN客户端与服务器端搭建操作
一.客户端的安装 1.点击安装程序 2.修改svn安装位置 3.开始安装 4.客户端安装成功 5.回到左面 右键出现svn检出 tortoiSVN 表示安装成功 Myeclipse svn插件安装 ...
- IDEA Intellij中vim插件使用小技巧
在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然 ...
- 模糊聚类算法(FCM)
伴随着模糊集理论的形成.发展和深化,RusPini率先提出模糊划分的概念.以此为起点和基础,模糊聚类理论和方法迅速蓬勃发展起来.针对不同的应用,人们提出了很多模糊聚类算法,比较典型的有基于相似性关系和 ...
- 剑指offer-第四章解决面试题思路(判断一个数组是否为二叉搜索树的后序遍历序列)
二叉搜索树:二叉搜索树根节点的左边都比根节点小,右边都比根节点大. 例题:输入一个数组,判断是否为二叉搜索树的后序遍历序列,如果是,返回true,如果不是,返回flase,假设没有重复的元素. 思路: ...