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调用的简单实现相关推荐

  1. RabbitMQ学习系列(五): RPC 远程过程调用

    前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用.不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/ca ...

  2. 130、RPC远程过程调用

    RPC简介 1. 什么是RPC 远程过程调用(英语:Remote Procedure Call,缩写为 RPC,也叫远程程序调用)是一个计算机通信协议.该协议允许运行于一台计算机的程序调用另一台计算机 ...

  3. rpc接口并发调用实例

    问题背景 需要根据id通过rpc调用查询具体信息,因为没有提供批量查询的接口,所以做法是挨个遍历查询,那意味着: 如果有100个id,就需要顺序进行100次rpc调用,假设每次rpc接口的调用时间是5 ...

  4. RPC 远程过程调用

    RPC简介 RPC,英文全称: Remote Procedure Call. 中文名: 远程过程调用,是一个计算机通讯协议.借助RPC可以像调用本地服务一样地调用远程服务.比如两台服务器订单服务器和商 ...

  5. java调c的接口_Java调用C接口的简单示例

    Java调用C接口的简单示例 正好需要用到Java调用dll里的C接口,想到自己做个简单的例子.我们可能需要自己生成dll文件,下边介绍一下,详细的步骤.主要参考https://blog.csdn.n ...

  6. 前端基础12:递归调用,快速排序和简单DOM元素操作

    递归调用 递归调用,方法自己调用自己(重复执行方法中的逻辑) 1.在方法内部调用自己的方法写在return 2.设置边界条件,让递归调用停下来 function fn(n) {if(n == 1){r ...

  7. C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);     public clas ...

  8. C++代码封装成dll供C#中调用、调用dll无可用源

    C#工程不可以直接调用C++的头文件和Lib库等 所以在程序中C#需要调用的现象,先将C++的东西封装成动态链接库,再调用 若调用dll时显示:无可用源调用,说明导入的DLL路径不对. 静态库和动态库 ...

  9. java调用怎么调用方法区_Java中的方法调用有多昂贵

    java调用怎么调用方法区 我们都去过那儿. 在查看设计不良的代码的同时,听听作者对人们永远不应该牺牲性能而不是设计的解释. 而且,您不能说服作者摆脱其500行方法,因为链接方法调用会破坏性能. 好吧 ...

  10. php教程调用数据库,PHP数据库调用类调用实例,php数据库调用实例_PHP教程

    PHP数据库调用类调用实例,php数据库调用实例 config("dns=aaa;uid=sa;pwd=sa;dbname=test"); //3.选择数据库 $dbname = ...

最新文章

  1. 从创业公司到AI巨头 出门问问如何定义下一代人机交互?
  2. spring3.0注解
  3. MDNS的漏洞报告——mdns的最大问题是允许广域网的mdns单播查询,这会暴露设备信息,或者被利用用于dns放大攻击...
  4. 《Total Commander:万能文件管理器》——第2.3节.下载与安装
  5. python联盟是什么意思_Python 与 英雄联盟(1)
  6. 牛客 - 弦(卡特兰数)
  7. python引用传递产生的问题_理解Python中传递值和引用时出现问题
  8. java日志——基本日志+高级日志
  9. MATLAB入门(二)
  10. ZOJ 1295——Reverse Text
  11. Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别、不可重复读与幻读的区别
  12. TCP洪水攻击(SYN Flood)的诊断和处理
  13. MyBatis查询返回Map类型数据
  14. 我讨厌电脑!一个系统管理员的自白
  15. Delphi动态事件深入分析
  16. 数据挖掘导论——可视化分析实验
  17. 彩虹六号按键精灵挂机脚本制作教程
  18. day13、1 - 抓包--科来软件使用
  19. 文件管理系统:5款优秀的文档管理系统
  20. 研究云计算中调度算法遇到的相关概念

热门文章

  1. php文本生成图片,php文本文字创建生成图片_PHP教程
  2. JS根据身份证号码获取性别
  3. 罗技无法使用计算机上的配置文件,Win10专业版罗技无线鼠标无法使用咋办?
  4. Netty实战《RPC调用》
  5. Python 2与Python 3对H5牌九棋牌搭建的区别
  6. 中小工厂的ERP和生产管理系统
  7. 优科Ruckus R610 AP刷Unleashed固件
  8. 形式语言与自动机总结
  9. 软件工程课程实践- 项目开发计划
  10. Microsemi Libero使用技巧5——使用FlashPro生成stp程序文件