netty的handler调用链机制

ChannelHandlerContext调用链(HeadContext、TailContext也是ChannelHandlerContext,ChannelHandlerContext内部维护了next和prev):
入站:DefaultChannelPipeline H e a d C o n t e x t ( 内 部 无 h a n d l e r 引 用 ) − − > D e f a u l t C h a n n e l H a n d l e r C o n t e x t ( T e s t S e r v e r I n i t i a l i z e r ( C h a n n e l I n i t i a l i z e r 也 是 h a n d l e r ) ) − − > D e f a u l t C h a n n e l H a n d l e r C o n t e x t ( H t t p S e r v e r C o d e c ) − − > D e f a u l t C h a n n e l H a n d l e r C o n t e x t ( T e s t H t t p S e r v e r H a n d l e r ) − − > D e f a u l t C h a n n e l P i p e l i n e HeadContext(内部无handler引用)-->DefaultChannelHandlerContext(TestServerInitializer(ChannelInitializer也是handler))-->DefaultChannelHandlerContext(HttpServerCodec) -->DefaultChannelHandlerContext(TestHttpServerHandler)-->DefaultChannelPipeline HeadContext(handler)>DefaultChannelHandlerContext(TestServerInitializer(ChannelInitializerhandler))>DefaultChannelHandlerContext(HttpServerCodec)>DefaultChannelHandlerContext(TestHttpServerHandler)>DefaultChannelPipelineTailContext(内部无handler引用)–>next为null,调用完毕
出站:DefaultChannelPipeline T a i l C o n t e x t ( 内 部 无 h a n d l e r 引 用 ) − − > D e f a u l t C h a n n e l H a n d l e r C o n t e x t ( T e s t H t t p S e r v e r H a n d l e r ) , T e s t H t t p S e r v e r H a n d l e r 为 入 站 处 理 器 , 跳 过 − − > D e f a u l t C h a n n e l H a n d l e r C o n t e x t ( H t t p S e r v e r C o d e c ) − − > D e f a u l t C h a n n e l H a n d l e r C o n t e x t ( T e s t S e r v e r I n i t i a l i z e r ( C h a n n e l I n i t i a l i z e r 也 是 h a n d l e r ) ) , 该 初 始 化 处 理 器 为 入 站 处 理 器 , 跳 过 − − > D e f a u l t C h a n n e l P i p e l i n e TailContext(内部无handler引用)-->DefaultChannelHandlerContext(TestHttpServerHandler),TestHttpServerHandler为入站处理器,跳过-->DefaultChannelHandlerContext(HttpServerCodec) -->DefaultChannelHandlerContext(TestServerInitializer(ChannelInitializer也是handler)),该初始化处理器为入站处理器,跳过-->DefaultChannelPipeline TailContext(handler)>DefaultChannelHandlerContext(TestHttpServerHandler),TestHttpServerHandler>DefaultChannelHandlerContext(HttpServerCodec)>DefaultChannelHandlerContext(TestServerInitializer(ChannelInitializerhandler)),>DefaultChannelPipelineHeadContext(内部无handler引用)
–>prev为null,调用完毕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Netty模拟RPC调用需要先了解RPC的基本概念和原理,以及Netty框架的使用方法。 RPC(Remote Procedure Call)远程过程调用是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用显式地编写远程调用的代码。RPC通常基于客户端/服务器模型,客户端向服务器发送RPC请求,服务器响应请求并返回结果。 Netty是一个高性能的、异步的、事件驱动的网络编程框架,它可以轻松地实现RPC调用。 下面是一个简单的Java代码示例,演示如何使用Netty模拟RPC调用: 1. 首先需要定义一个接口,这个接口定义了要远程调用的方法: ```java public interface HelloService { String sayHello(String name); } ``` 2. 接下来创建一个实现类,实现HelloService接口: ```java public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "Hello, " + name + "!"; } } ``` 3. 创建一个服务端程序,启动Netty服务端,并将HelloServiceImpl注册到服务端: ```java public class Server { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null))); pipeline.addLast(new ObjectEncoder()); pipeline.addLast(new ServerHandler()); } }); ChannelFuture f = b.bind(8888).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } private static class ServerHandler extends SimpleChannelInboundHandler<Object> { @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof RpcRequest) { RpcRequest request = (RpcRequest) msg; String className = request.getClassName(); String methodName = request.getMethodName(); Class<?>[] parameterTypes = request.getParameterTypes(); Object[] parameters = request.getParameters(); // 根据类名获取实现类 Class<?> clazz = Class.forName(className); Object service = clazz.newInstance(); // 根据方法名和参数类型获取方法 Method method = clazz.getMethod(methodName, parameterTypes); // 执行方法 Object result = method.invoke(service, parameters); // 返回结果 ctx.writeAndFlush(result); } } } } ``` 4. 创建一个客户端程序,通过Netty客户端向服务端发送RPC请求: ```java public class Client { public static void main(String[] args) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ObjectEncoder()); pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null))); pipeline.addLast(new ClientHandler()); } }); ChannelFuture f = b.connect("localhost", 8888).sync(); // 发送RPC请求 RpcRequest request = new RpcRequest(); request.setClassName("com.example.HelloServiceImpl"); request.setMethodName("sayHello"); request.setParameterTypes(new Class<?>[] { String.class }); request.setParameters(new Object[] { "world" }); f.channel().writeAndFlush(request); // 等待响应 f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } private static class ClientHandler extends SimpleChannelInboundHandler<Object> { @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { // 处理响应结果 System.out.println(msg); ctx.channel().close(); } } } ``` 这样,我们就通过Netty模拟了一次RPC调用。当客户端向服务端发送RPC请求时,服务端会根据请求参数调用相应的方法并返回结果,客户端收到响应结果后输出到控制台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值