【Netty4 简单项目实践】一、长连接服务通用框架原型

12 篇文章 0 订阅
9 篇文章 0 订阅

第一个版本实现面向字符串的TCP长连接服务

看点:Liunx优化、TCP连接设置


服务端通用框架

在Netty4中,所有的服务端使用相同的框架结构。
  1. 生成一个ServerBootstrap对象
  2. 在ServerBootstrap对象的group中添加“接收消息循环队列”和“发送消息循环队列”两个对象
  3. 在ServerBootstrap对象上设置连接的属性(比如TCP连接属性:收发包缓冲区大小、TCP connect超时时间)
  4. 添加处理器Handler容器对象
  5. 在Handler容器内加载handler实例
下面是一个可以用的String消息的处理框架:

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

    EventLoopGroup bossLoopnew NioEventLoopGroup(); //接收消息循环队列

    EventLoopGroup workerLoopnew NioEventLoopGroup(); //发送消息循环队列

    try{

        ServerBootstrap bootstrap = new ServerBootstrap();

        bootstrap.group(bossLoop, workerLoop) //加载消息循环队列

            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)

            .option(ChannelOption.TCP_NODELAY, true); //TCP立即发包

        bootstrap.channel(NioServerSocketChannel.class);

        bootstrap.localAddress(new InetSocketAddress(port))

                .childHandler(new ChannelInitializer<Channel>() {

                    @Override

                    protected void initChannel(Channel ch) throws Exception {

                        // TODO Auto-generated method stub

                        ChannelPipeline pipeline = ch.pipeline();

                        pipeline.addLast(new StringDecoder()); //Netty4自带的String解码器

                        pipeline.addLast(new StringEncoder()); //Netty4自带的String编码器

                        pipeline.addLast(new MyHandler()); // 自己实现的处理器

                    }

                });

        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        ChannelFuture future = bootstrap.bind(port).sync();

        if (future.isSuccess()){}

        future.channel().closeFuture().sync();

    } catch (Exception e) {

            

    } finally {

        workerLoop.shutdownGracefully();

        bossLoop.shutdownGracefully();

    }

}


file:MyHandler.java


public class ProtoBufHandler extends SimpleChannelInboundHandler<Protocol> { 

    @Override

    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        System.out.println(msg);

        ctx.writeAndFlush(msg);

        ctx.close();

    }

}
到此就实现了一个简单的TCP字符串处理程序

【重要】

针对Linux的性能优化

上面的消息循环队列使用的跨平台方案NioEventLoopGroup对象。而对于Linux系统来说,其实是可以使用epoll模型的对象 EpollEventLoopGroup。
代码如下:

    String osName = System.getProperty("os.name");

    EventLoopGroup bossLoop = null;

    EventLoopGroup workerLoop = null;

    if (osName.equals("Linux")) {

        bossLoop = new EpollEventLoopGroup();

        workerLoop = new EpollEventLoopGroup();

    } else {

        bossLoop = new NioEventLoopGroup();

        workerLoop = new NioEventLoopGroup();

    }


对bootstrap的channel也要设置一下

    if (osName.equals("Linux")) { //Linux平台用Epoll模式

        bootstrap.channel(EpollServerSocketChannel.class);

    } else {

        bootstrap.channel(NioServerSocketChannel.class);

    }

TCP连接属性设置

很多文章一股脑把tcp连接属性都加上了,其实很多是不必要的,例如keepAlive。常用的如下:

bootstrap.group(bossLoop, workerLoop)

                //keepAlive默认是打开

                //.option(ChannelOption.SO_KEEPALIVE, true)

                // 默认采用AdaptiveRecvByteBufAllocator分配器,不需要配置

                //.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)

                //PooledByteBufAllocator这种分配器是默认分配器,当buffer被写入下一个节点的时候,它会

                //自动释放,并放入pool里面

                //.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)

                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)

                .option(ChannelOption.SO_SNDBUF, 1024*256) //发包缓冲区,单位多少?

                .option(ChannelOption.SO_RCVBUF, 1024*256) //收包换成区,单位多少?

                .option(ChannelOption.TCP_NODELAY, true); //TCP立即发包


完工,交差
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值