学习Netty的第一天


写在文章前:知识来源为《B站》视屏和《netty实战中文版》书籍

Netty基础

Netty官网

  • C/S模式、异步

使用idea创建一个简单的异步服务

客户端处理配置类

```
/**
* @Description: 客户端处理配置类
* @Author: Lmy
* @Date: 2020/10/16 4:49 下午
*/
@ChannelHandler.Sharable//表示可以被多个channel安全共享
public class HandlerMonitorClient extends SimpleChannelInboundHandler<ByteBuf> {

    /**
     * @Date: 2020/10/16 4:52 下午
     * @Author: Lmy
     * @Description: 消息接收处理
    */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
        System.out.println(byteBuf.toString(CharsetUtil.UTF_8));
    }

    /**
     * @Date: 2020/10/16 4:52 下午
     * @Author: Lmy
     * @Description: 异常处理
    */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * @Date: 2020/10/16 6:44 下午
     * @Author: Lmy
     * @Description: 通道第一次成功连接的时候触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("通道第一次成功连接的时候触发");
        SimpleDateFormat simpleFormatter=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        String format = simpleFormatter.format(new Date());
        ctx.writeAndFlush(Unpooled.copiedBuffer(format,CharsetUtil.UTF_8));
    }

    /**
     * @Date: 2020/10/16 6:50 下午
     * @Author: Lmy
     * @Description: 通道第一次失效的时候调用
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("通道第一次失效的时候调用");
    }
}		
```

客户端启动类

/**
 * @Description: 客户端启动类
 * @Author: Lmy
 * @Date: 2020/10/16 5:03 下午
 */

public class AppMonitorClient {
    private final int port;
    private final String host;


    public AppMonitorClient(int port, String host) {
        this.port = port;
        this.host = host;
    }

    /**
     * @Date: 2020/10/16 5:06 下午
     * @Author: Lmy
     * @Description:
    */
    public void run() throws Exception{
        EventLoopGroup eventExecutors=new NioEventLoopGroup(); //io线程池

        Bootstrap bootstrap=new Bootstrap();//辅助启动类
        try {
            //配置辅助启动类
            bootstrap.group(eventExecutors)//使用的线程
                    .channel(NioSocketChannel.class)//链接什么类型的通道
                    .remoteAddress(new InetSocketAddress(host,port)) //绑定地址端口
                    .handler(new ChannelInitializer<SocketChannel>() {//初始化通道配置
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //pipeline(责任链) 所有的Handler都存在这里
                            socketChannel.pipeline().addLast(new HandlerMonitorClient());//添加自定义通道
                        }
                    });
            //链接到远端 等待链接完成
            ChannelFuture sync = bootstrap.connect().sync();
            //发送消息到服务端  在通道中写数据并且提交
            sync.channel().writeAndFlush(Unpooled.copiedBuffer("hello world",CharsetUtil.UTF_8));
            //阻塞操作 closeFuture()开启了一个channel监听 通道关闭的时候执行
            sync.channel().closeFuture().sync();
        } finally {
            //资源释放
            eventExecutors.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) {
        try {
            new AppMonitorClient(8080,"127.0.0.1").run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务器配置类


/**
 * @Description: 服务器 io处理类  连接监测
 * @Author: Lmy
 * @Date: 2020/10/16 5:59 下午
 */

@ChannelHandler.Sharable
public class HandlerMonitorServer extends ChannelInboundHandlerAdapter {

    //存储所有的Channel
    public static ChannelGroup channelGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * @Date: 2020/10/16 6:06 下午
     * @Author: Lmy
     * @Description: 处理信息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        System.out.println(in.toString(CharsetUtil.UTF_8));//处理接收到的数据

        //返回信息给客户端
        ctx.writeAndFlush(Unpooled.copiedBuffer("收到信息", CharsetUtil.UTF_8));
    }

    /**
     * @Date: 2020/10/16 6:04 下午
     * @Author: Lmy
     * @Description: 重写处理异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * @Date: 2020/10/16 6:40 下午
     * @Author: Lmy
     * @Description: 连接建立后触发 添加到容器
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

        Channel channel = ctx.channel();
        System.out.println("连接建立后触发 添加到容器");
        channelGroup.add(channel);
    }

    /**
     * @Date: 2020/10/16 6:43 下午
     * @Author: Lmy
     * @Description: 连接断开触发 从容器中移除
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("连接断开触发 从容器中移除");
        channelGroup.remove(channel);
    }

    /**
     * @Date: 2020/10/16 6:44 下午
     * @Author: Lmy
     * @Description: 通道第一次成功连接的时候触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("通道第一次成功连接的时候触发");
        SimpleDateFormat simpleFormatter=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        String format = simpleFormatter.format(new Date());
        ctx.writeAndFlush(Unpooled.copiedBuffer(format,CharsetUtil.UTF_8));
    }

    /**
     * @Date: 2020/10/16 6:50 下午
     * @Author: Lmy
     * @Description: 通道第一次失效的时候调用
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("通道第一次失效的时候调用");
    }
}

服务器启动类

/**
 * @Description: 服务器启动类
 * @Author: Lmy
 * @Date: 2020/10/16 6:09 下午
 */

public class AppMonitorServer {
    private final int port;


    public AppMonitorServer(int port) {
        this.port = port;
    }

    /**
     * @Date: 2020/10/16 5:06 下午
     * @Author: Lmy
     * @Description:
     */
    public void run() throws Exception {
        EventLoopGroup eventExecutors = new NioEventLoopGroup(); //io线程池

        ServerBootstrap serverBootstrap = new ServerBootstrap();//辅助启动类
        try {
            //配置辅助启动类
            serverBootstrap.group(eventExecutors)//使用的线程
                    .channel(NioServerSocketChannel.class)//链接什么类型的通道
                    .localAddress(new InetSocketAddress(port)) //监听端口
                    .childHandler(new ChannelInitializer<SocketChannel>() {//初始化通道配置
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //pipeline(责任链) 所有的Handler都存在这里
                            socketChannel.pipeline().addLast(new HandlerMonitorServer());//添加自定义通道
                        }
                    });
            //绑定服务器
            ChannelFuture sync = serverBootstrap.bind().sync();

            //阻塞操作 closeFuture()开启了一个channel监听  当通道关闭的时候执行
            sync.channel().closeFuture().sync();
        } finally {
            //资源释放
            eventExecutors.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {

        new AppMonitorServer(8080).run();

    }
}

学习小结

  • 客户端建立通道并绑定地址与端口
  • 服务器绑定端口并监听行为
  • 所有操作都是在异步处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值