《Netty实战》读书笔记(一)(下)

简介: 《Netty实战》读书笔记(一)(下)

编写服务端



ChannelHandler - 接受客户端数据

  • channelRead()
  • 对每个传入的消息都要调用;
  • channelReadComplete()
  • 通过ChannelInboundHandler 最后一个对 channel-Read() 的调用是当前批量读取中的最后一条消息;
  • exceptionCaught()
  • 在读取操作期间,有异常抛出时会调用j

方式:

继承CahnelInboundHandlerAdapter的方式


不捕获异常,会发生什么情况


每个Channel 拥有一个关联的ChannelPipeline,如果没有实现,会放到Piepeline的尾端,但是,必须有一个实现了捕获异常的Caught()方法

  • 针对不同事件,调用handler
  • 使用责任链加上事件响应的方式处理


引导服务器启动


  • 业务逻辑增加了之后,需要启动这个Channel监听请求
  • 配置Channel,将入站信息通知给handler实例


创建传输的server


  • 建立我们自己实现的channelHandler EchoServer对象
  • 创建EventLoopGroup,用来处理channel
  • 创建boostrapServer,用于建立套接字连接
  • 设置group
  • 使用NIOSocket 套接字
  • 设置请求接受端口
  • 设置子channel的channelHandler
  • 初始化调用,设置新的channel  -> 就是我们自我实现的EchoServer
  • 设置future, 使用异步开启服务器并且阻塞线程等待结果
  • 获取futurecloseFuture,同样阻塞等待所有任务结束之后发送通知
  • 最后,finally 方法关闭group,并且释放所有的资源

如果想要使用阻塞的IO要如何处理:

OioServerSocketChannel OioEventLoopGroup


示范代码:



EchoServer:我们实现的channelHandler


public class EchoServer extends ChannelInboundHandlerAdapter {
    /**
     * 读取事件
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        System.err.println("Server receive" + in.toString(CharsetUtil.UTF_8));
    }
    /**
     * 最后一次读取完成之后,发送通知到channelHandler
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }
    /**
     * 读取的过程
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
复制代码


EchoServerClinet:服务器客户端开启


public class EchoServerClient {
    private static final int PORT = 8080;
    public static void main(String[] args) throws InterruptedException {
        if(args.length > 1){
            System.err.println("server ");
        }
        final EchoServer echoServer = new EchoServer();
        // 创建事件驱动器 EventLoopGroup
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        try{
            // 创建server bootstrap
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            // 1. 指定使用NIO传输的渠道
            // 2. 指定端口
            // 3. 添加一个echoseverhandler 到子channel的chanelPipeline
            serverBootstrap.group(eventLoopGroup)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(PORT))
                    .childHandler(new ChannelInitializer() {
                        // 很关键,需要使用pipeline加入事件来帮我们处理channel
                        protected void initChannel(Channel ch) throws Exception {
                            ch.pipeline().addLast(echoServer);
                        }
                    });
            // 阻塞当前线程,异步绑定服务器
            ChannelFuture channelFuture = serverBootstrap.bind().sync();
            // 获取当前channel的closeFuture,阻塞直到线程完成
            channelFuture.channel().closeFuture().sync();
        }finally {
            // 关闭group 释放资源
            eventLoopGroup.shutdownGracefully().sync();
        }
    }
}
复制代码


编写客户端



客户端需要做的事情比较简单,只需要如下步骤:

  • 建立一个与socket的连接
  • 发送一条或者多条消息
  • 对于每一条消息,等待服务器返回处理的数据
  • 关闭连接


chanelHandler实现客户端


  • 继承SimpleChannelInboundHandler
  • 实现方法channelRead0()从服务器收到消息之后,会调用这个方法
  • 重写channelActive(),被通知channel活跃的时候发送通知
  • 重写exceptionCaught(),处理异常


为什么客户端要使用SimpleChannelInboundHandler而不是服务端的ChannelInboundHandlerAdapter

SimpleChannelInboundHandler 在处理完传入消息之后,理论上一个请求就已经被处理完成,此时channel会该类默认会释放这条传入消息的内存引用

ChannelInboundHandlerAdapter处理完消息之后,此时channelRead()结果不一定返回,因为整个过程都是异步的

问题又来了,什么时候会释放channelRead()处理之后的消息资源呢

答:当channelComplete()writeAndFlush()之后,该消息资源才会被真正释放


运行案例



  • 启动EchoServerClient
  • 启动EchoClientServer


总结



以上就是一个最为简单的netty Demo

后续的笔记将会深入到netty的几个关键点


  • Channel
  • CahnnelHandler
  • Futrue
  • BootstrapServer
  • EventLoop
  • EventLoopGroup
相关文章
|
4月前
Netty实战: HTTP文件列表服务器
Netty实战: HTTP文件列表服务器
49 0
|
4月前
|
Java Unix Linux
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
当涉及到网络通信和高性能的Java应用程序时,Netty是一个强大的框架。它提供了许多功能和组件,其中之一是JNI传输。JNI传输是Netty的一个特性,它为特定平台提供了高效的网络传输。 在本文中,我们将深入探讨Netty提供的特定平台的JNI传输功能,分析其优势和适用场景。我们将介绍每个特定平台的JNI传输,并讨论其性能、可靠性和可扩展性。通过了解这些特定平台的JNI传输,您将能够更好地选择和配置适合您应用程序需求的网络传输方式,以实现最佳的性能和可靠性。
124 7
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
|
4月前
|
网络协议 Java 测试技术
阿里内部Netty实战小册,值得拥有
Netty 是一个高性能的 Java 网络通信框架,简化了网络编程并涵盖了最新的Web技术。它提供了一种抽象,降低了底层复杂性,使得更多开发者能接触网络编程。Netty 因其易用性、高效性和广泛的应用场景受到推崇,适合互联网行业从业者学习,有助于理解和开发基于Netty的系统。免费的《Netty实战小册》详细介绍了Netty的各个方面,包括概念、架构、编解码器、网络协议和实际案例,帮助读者深入理解和应用Netty。如需完整版小册,可点击链接获取。
阿里内部Netty实战小册,值得拥有
|
1月前
|
前端开发 网络协议
Netty实战巅峰:从零构建高性能IM即时通讯系统,解锁并发通信新境界
【8月更文挑战第3天】Netty是一款高性能、异步事件驱动的网络框架,适用于开发高并发网络应用,如即时通讯(IM)系统。本文将指导你利用Netty从零构建高性能IM程序,介绍Netty基础及服务器/客户端设计。服务器端使用`ServerBootstrap`启动,客户端通过`Bootstrap`连接服务器。示例展示了简单的服务器启动过程。通过深入学习,可进一步实现用户认证等功能,打造出更完善的IM系统。
67 1
|
1月前
|
编解码 NoSQL Redis
(十一)Netty实战篇:基于Netty框架打造一款高性能的IM即时通讯程序
关于Netty网络框架的内容,前面已经讲了两个章节,但总归来说难以真正掌握,毕竟只是对其中一个个组件进行讲解,很难让诸位将其串起来形成一条线,所以本章中则会结合实战案例,对Netty进行更深层次的学习与掌握,实战案例也并不难,一个非常朴素的IM聊天程序。
|
1月前
|
移动开发 网络协议 算法
(十)Netty进阶篇:漫谈网络粘包、半包问题、解码器与长连接、心跳机制实战
在前面关于《Netty入门篇》的文章中,咱们已经初步对Netty这个著名的网络框架有了认知,本章的目的则是承接上文,再对Netty中的一些进阶知识进行阐述,毕竟前面的内容中,仅阐述了一些Netty的核心组件,想要真正掌握Netty框架,对于它我们应该具备更为全面的认知。
|
4月前
|
NoSQL Redis
Netty实战:模拟Redis的客户端
Netty实战:模拟Redis的客户端
69 0
|
4月前
|
缓存 NoSQL Java
聚焦实战技能,剖析底层原理:Netty+Redis+ZooKeeper+高并发实战
移动时代、5G时代、物联网时代的大幕已经开启,它们对于高性能、高并发的开发知识和技术的要求,抬升了Java工程师的学习台阶和面试门槛。
|
4月前
|
分布式计算 前端开发 网络协议
13W字!腾讯高工手写“Netty速成手册”,3天能走向实战
在java界,netty无疑是开发网络应用的拿手菜。你不需要太多关注复杂的nio模型和底层网络的细节,使用其丰富的接口,可以很容易的实现复杂的通讯功能。
|
4月前
|
监控 网络协议 调度
Netty Review - 深入探讨Netty的心跳检测机制:原理、实战、IdleStateHandler源码分析
Netty Review - 深入探讨Netty的心跳检测机制:原理、实战、IdleStateHandler源码分析
315 0