【netty in action】学习笔记-第二章 编写你的第一个netty程序

【netty in action】学习笔记-第二章 编写你的第一个netty程序

这一章简单粗暴,整个章节都是讲一个例子,例子很简单,但是麻雀虽小五脏俱全。通过这个示例你会对编写基于netty的应用程序有个直观的认识。

我先上代码,后面再分析。

先看看服务端的示例,

public class EchoServer {
    public int port;

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

    public void start() {

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    });

            ChannelFuture f = b.bind().sync();
            System.out.println(EchoServer.class.getName() + "started and listen on " + f.channel().localAddress());
            f.channel().closeFuture().sync();
        }catch (Exception e) {

        }finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new EchoServer(8888).start();
    }
}

public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.copiedBuffer("netty rocks", CharsetUtil.UTF_8));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf msg) throws Exception {

        ByteBuf recieveMsg=(ByteBuf) msg;
        String result = ByteBufUtil.hexDump(recieveMsg).toUpperCase();//将bytebuf中的可读字节 转换成16进制数字符串
        String result2 = ByteBufUtil.hexDump(msg.readBytes(msg.readableBytes()));
        //看下两种方式输出的结果有什么区别
        System.out.println("client received:" + result);
        System.out.println("client received:" + result2);

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

然后是客户端的示例,

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

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

    public void start() throws InterruptedException {

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(host, port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {

                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });

            ChannelFuture f = b.connect().sync();
            f.channel().closeFuture().sync();

        }catch (Exception e) {

        }finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) {
        String host = "127.0.0.1";
        int port = 8888;

        new EchoClient(host, port).start();
    }
}
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.write(Unpooled.copiedBuffer("netty rocks", CharsetUtil.UTF_8));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf msg) throws Exception {

        ByteBuf recieveMsg=(ByteBuf) msg;
        String result = ByteBufUtil.hexDump(recieveMsg).toUpperCase();//将bytebuf中的可读字节 转换成16进制数字符串
        String result2 = ByteBufUtil.hexDump(msg.readBytes(msg.readableBytes()));
        //看下两种方式输出的结果有什么区别
        System.out.println("client received:" + result);
        System.out.println("client received:" + result2);

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

这个代码是可以运行的。你可以自己跑一下。

下面就来解释下上面这些代码。当然这里只做简单的解释,因为每个概念在后面的章节都有详细的描述。

Bootstrap用来启动服务,客户端和服务端都使用这个。区别在于服务端使用的是ServerBootstrap。这两个类都是继承自AbstractBootstrap这个抽象类。

NioEventLoopGroup用来处理多个连接,可以把它理解为线程池。

NioServerSocketChannel当然就是netty里最核心的概念channel。这里我们指定channel的类型。当然这里你可以指定OioServerSocketChannel,表示阻塞的IO channel。

我们通过childHandler指定业务处理核心逻辑的handler,这些handler是以链的方式管理的。ChannelPipeline是这个链的名字。这其实也是设计模式中的责任链模式。

接着我们通过bind方法绑定服务器,sync表示这是一个阻塞的同步调用,在绑定成功之前都会等待。

EchoServerHandlerEchoClientHandler是我们业务处理类,他们的设计方法就是我们前面章节说到的回调。看房方法的名字也能猜出一二。我们需要继承ChannelInboundHandlerAdapter表明这是一个入口处的处理类。(出口和入口的后面会详细说明)。

channelRead方法在服务端(客户端)收到数据时被调用,exceptionCaught是异常发生时调用。

需要注意的是,在接收数据的时候,channelRead(channelRead0)可能会调用多次,比如接收5个字节,第一次收到3个,第二次收到2个。这其实是netty里面拆包,粘包的概念,这个在后面的章节也会讲到,这里不多说。尽管会出现拆包,粘包的情况,但是netty能保证在TCP协议下,数据接收的顺序和发送的顺序是一致的。(这个也是netty很多自带的解码器处理粘包的前提)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Netty-WebSocket-Spring-Boot-Starter是一个用于将Websocket集成到Spring Boot应用程序中的库。它使用Netty作为底层框架,提供了一种快速和可靠的方式来处理异步通信。 这个库提供了一种简单的方法来创建Websocket端点,只需要使用注释和POJO类即可。在这些端点上可以添加动态的事件处理程序,以处理连接、断开连接和消息事件等。 此外,Netty-WebSocket-Spring-Boot-Starter还包括了一些安全性的特性,如基于令牌的授权和XSS保护,可以帮助您保持您的Websocket应用程序安全。 总的来说,Netty-WebSocket-Spring-Boot-Starter提供了一种快速和易于使用的方式来构建Websocket应用程序,使得它成为应用程序开发人员的有用工具。 ### 回答2: netty-websocket-spring-boot-starter 是一个开源的 Java Web 开发工具包,主要基于 Netty 框架实现了 WebSocket 协议的支持,同时集成了 Spring Boot 框架,使得开发者可以更加方便地搭建 WebSocket 服务器。 该工具包提供了 WebSocketServer 配置类,通过在 Spring Boot 的启动配置类中调用 WebSocketServer 配置类,即可启动 WebSocket 服务器。同时,该工具包还提供了多种配置参数,如端口号、URI 路径、SSL 配置、认证配置等等,可以根据业务需求进行自定义配置。 此外,该工具包还提供了一些可扩展的接口和抽象类,如 WebSocketHandler、ChannelHandlerAdapter 等,可以通过继承和实现这些接口和抽象类来实现业务逻辑的处理和拓展。 总的来说,netty-websocket-spring-boot-starter 提供了一个高效、简单、易用的 WebSocket 服务器开发框架,可以减少开发者的开发成本和工作量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值