美文网首页
(一)第一个netty的demo

(一)第一个netty的demo

作者: guessguess | 来源:发表于2021-02-19 15:34 被阅读0次

    由于在公司闲的蛋疼,看到Nio比较diao,所以开始学习起来,先实现一个简单的demo。

    使用maven进行项目管理,依赖如下

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.gee</groupId>
      <artifactId>my-netty</artifactId>
      <version>0.0.1-SNAPSHOT</version>
        <dependencies>
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.16.Final</version>
            </dependency>
    
    
            <!-- 时间工具类 start -->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>2.9</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <!-- 指定maven编译的jdk的版本 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    

    工程目录如下


    工程项目结构

    那么动手来先构建服务端

    config连接配置,配置如下

    package config;
    
    public class ConnectConfig {
        private static final String host = "127.0.0.1";
        private static final int port = 9527;
        private static final int SO_BACKLOG = 1024;
        public static int getPort() {
            return port;
        }
        public static String getHost() {
            return host;
        }
        public static int getSoBacklog() {
            return SO_BACKLOG;
        }
        
    }
    
    

    server

    (一)服务的启动类

    package server;
    
    import config.ConnectConfig;
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import server.handler.TimeServerChannelHandler;
    
    public class TimeServer {
        public static void main(String arg[]) {
            //启动服务类
            startServer();
        }
    
        private static void startServer() {
            //用于处理accept事件
            EventLoopGroup boss = new NioEventLoopGroup();
            //用于处理通道的读写事件
            EventLoopGroup work = new NioEventLoopGroup();
    
            ServerBootstrap sb = new ServerBootstrap();
            //主线程其实就是serverSocket,这里使用的是Nio,所以需要指定类型为NioServerSocketChannel
            //childHandler,其实自己定义如何处理,服务端这边的通道
            sb.group(boss, work).option(ChannelOption.SO_BACKLOG, ConnectConfig.getSoBacklog())
                    .channel(NioServerSocketChannel.class).childHandler(new TimeServerChannelHandler());
    
            ChannelFuture cf = null;
            try {
                //服务端绑定端口,直到绑定成功,会一直阻塞
                cf = sb.bind(ConnectConfig.getPort()).sync();
                //服务端的主通道,直到等到关闭,会一直阻塞
                cf.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //将对应的监听线程关闭,避免线程没有杀死
                boss.shutdownGracefully();
                work.shutdownGracefully();
            }
        }
    }
    
    

    (二)服务的对于子通道的处理器

    package client.handler;
    
    import client.handler.adapter.TimeClientChannelHandlerAdapter;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.socket.SocketChannel;
    
    public class TimeClientHandler extends ChannelInitializer<SocketChannel>{
    
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new TimeClientChannelHandlerAdapter());
        }
    }
    

    (三)服务的对于子通道的处理器适配器

    package client.handler.adapter;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    public class TimeClientChannelHandlerAdapter extends ChannelInboundHandlerAdapter{
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            String req = "what time it is";
            ctx.writeAndFlush(Unpooled.copiedBuffer(req.getBytes()));
        }
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf req = (ByteBuf) msg;
            byte[] reqinfo = new byte[req.readableBytes()];
            req.readBytes(reqinfo);
            System.out.println("now is " + new String(reqinfo, "UTF-8"));
        }
    }
    
    

    那么动手来先构建客户端

    (一)客户端的启动类

    package client;
    
    import client.handler.TimeClientHandler;
    import config.ConnectConfig;
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    public class TimeClient {
        public static void main(String args[]) {
            connect();
        }
        
        private static void connect() {
            //用于客户端处通道的读写
            EventLoopGroup work = new NioEventLoopGroup();
            
            Bootstrap b = new Bootstrap();
            b.group(work).option(ChannelOption.TCP_NODELAY, true).channel(NioSocketChannel.class)
                    .handler(new TimeClientHandler());
            ChannelFuture cf = null;
            try {
                //一直阻塞,直到连接上服务端
                cf = b.connect(ConnectConfig.getHost(), ConnectConfig.getPort()).sync();
                //一直阻塞,直到该通道关闭
                cf.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //避免线程没有杀死
                work.shutdownGracefully();
            }
        }
    }
    

    (二)客户端的对于通道的处理器

    package client.handler;
    
    import client.handler.adapter.TimeClientChannelHandlerAdapter;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.socket.SocketChannel;
    
    public class TimeClientHandler extends ChannelInitializer<SocketChannel>{
    
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new TimeClientChannelHandlerAdapter());
        }
    }
    
    

    (三)客户端的对于通道的处理器适配器

    package client.handler.adapter;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    public class TimeClientChannelHandlerAdapter extends ChannelInboundHandlerAdapter{
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            String req = "what time it is";
            ctx.writeAndFlush(Unpooled.copiedBuffer(req.getBytes()));
        }
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf req = (ByteBuf) msg;
            byte[] reqinfo = new byte[req.readableBytes()];
            req.readBytes(reqinfo);
            System.out.println("now is " + new String(reqinfo, "UTF-8"));
        }
    }
    

    最后运行,结果如下

    服务端收到来自客户端的请求:what time it is
    客户端得到服务端的响应:now is 2021-02-18T10:41:30.068+08:00
    
    服务端
    客户端

    相关文章

      网友评论

          本文标题:(一)第一个netty的demo

          本文链接:https://www.haomeiwen.com/subject/scygxltx.html