美文网首页
netty学习笔记

netty学习笔记

作者: jinelei | 来源:发表于2019-02-15 16:37 被阅读0次

1. 创建maven工程

<dependency>
  <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.30.Final</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
  </dependency>

添加netty-all和junit,junit做单元测试用

2. 添加server主类

/**
 * @author zhenlei
 */
public class MainServer {
    private EventLoopGroup bossGroup = null;
    private EventLoopGroup workerGroup = null;
    private ServerBootstrap bootstrap = null;
    private int port = 8080;
    private int status = 0;


    /**
     * 设置,只执行一次
     *
     * @param optionalPort
     */
    public void setup(Optional<Integer> optionalPort) {
        if (status == 0) {
            if (optionalPort.isPresent()) {
                port = optionalPort.get();
            }
            Assert.assertNull("主进程不为空", bossGroup);
            Assert.assertNull("工作进程不为空", workerGroup);
            Assert.assertNull("启动器不为空", bootstrap);
            bossGroup = new NioEventLoopGroup();
            workerGroup = new NioEventLoopGroup();
            bootstrap = new ServerBootstrap();
        } else {
            throw new RuntimeException("服务器已经启动");
        }
    }

    /**
     * 获取server状态
     *
     * @return
     */
    public String getStatus() {
        StringBuffer sb = new StringBuffer(6);
        sb.append(bossGroup.isShutdown() ? "1" : "0");
        sb.append(bossGroup.isShuttingDown() ? "1" : "0");
        sb.append(bossGroup.isTerminated() ? "1" : "0");
        sb.append(workerGroup.isShutdown() ? "1" : "0");
        sb.append(workerGroup.isShuttingDown() ? "1" : "0");
        sb.append(workerGroup.isTerminated() ? "1" : "0");
        return sb.toString();
    }

    /**
     * 启动server
     *
     * @param initializer 注入ChannelInitializer
     * @return
     * @throws Exception
     */
    public ChannelFuture startup(ChannelInitializer<SocketChannel> initializer) throws Exception {
        Assert.assertNotNull("主进程为空", bossGroup);
        Assert.assertNotNull("工作进程为空", workerGroup);
        Assert.assertNotNull("启动器为空", bootstrap);
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(initializer)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true);
        ChannelFuture future = bootstrap.bind(port).sync();
        System.out.println(String.format("server start http://127.0.0.1:%d", port));
        return future;
    }

    /**
     * 关闭server
     *
     * @throws Exception
     */
    public void shutdown() throws Exception {
        System.out.println(String.format("server shutdown  http://127.0.0.1:%d", port));
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        // 确认停止server
        if (workerGroup.isShuttingDown() || !workerGroup.isTerminated() || !workerGroup.isShutdown()) {
            workerGroup.shutdownGracefully();
        }
        if (bossGroup.isShuttingDown() || !bossGroup.isTerminated() || !bossGroup.isShutdown()) {
            bossGroup.shutdownGracefully();
        }
    }
}

3. 创建Handler和对应的ChannelInitialzer

EchoHandler,收到消息直接输出

/**
 * @author zhenlei
 */
public class EchoHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ctx.writeAndFlush(msg);
    }

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

EchoChannelInitialzer

/**
 * @author zhenlei
 */
public class EchoChannelInitialzer extends ChannelInitializer<SocketChannel> {
    @Override
    public void initChannel(SocketChannel ch) {
        ch.pipeline().addLast(new EchoHandler());
    }

}

4. 创建测试类

public class MainServerTest {
    MainServer mainServer = null;

    @Before
    public void setup() {
        mainServer = new MainServer();
        mainServer.setup(Optional.empty());
    }

    @Test
    public void testDiscard() throws Exception {
        System.out.println("testDiscard");
        mainServer.startup(new DiscardChannelInitialzer());
        Thread.sleep(10000);
    }

    @Test
    public void testEcho() throws Exception {
        System.out.println("testEcho");
        mainServer.startup(new EchoChannelInitialzer());
        Thread.sleep(10000);
    }

    @Test
    public void testHello() throws Exception {
        System.out.println("testHello");
        mainServer.startup(new HelloChannelInitialzer());
        Thread.sleep(10000);
    }

    @After
    public void cleanup() throws Exception {
        mainServer.shutdown();
    }
}

相关文章

网友评论

      本文标题:netty学习笔记

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