Netty 服务端

启动接口


public interface StartAble {

    /**
     * 启动
     */
    void on();

    /**
     * 停止
     */
    void off();
}

NioSocketServer


@Slf4j
public class NioSocketServer  implements Runnable , StartAble {


    public NioSocketServer( ) {

    }

    NioEventLoopGroup boss ;
    NioEventLoopGroup works ;
    Channel channel;



    @Override
    public void run() {
        on();
    }

    @Override
    public void on() {

        boss =  new NioEventLoopGroup();

        works = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();

        serverBootstrap
                //组装线程池用来处理 channel 连接
                .group(boss,works)

                .channel(NioServerSocketChannel.class)

                //设置tcp 队列长度   阻塞队列 +  接受 队列 = so_backlog 长度 说明:https://www.jianshu.com/p/e6f2036621f4
                .option(ChannelOption.SO_BACKLOG,1024)

                //子配置项  是否保持tcp 长连接(心跳包监听)  两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
                .childOption(ChannelOption.SO_KEEPALIVE,true)

                //子配置项  是否立即发送数据 (立即 或者攒够一定数据)
                .childOption(ChannelOption.TCP_NODELAY,true)

                //子处理项
                .childHandler(new WorksChannelInitializer());

        try {
            System.out.println("----------");

            ChannelFuture future = serverBootstrap.bind(new InetSocketAddress("127.0.0.1",13140)).sync();

            channel = future.channel();

            log.info("服务器启动开始监听端口: {}", 9999);

            /*
             * ChannelFuture 保存异步执行结果
             * closeFuture() : 如果关闭则返回future实例  (始终返回相同的实例)
             * sync() : 等待这个异步执行完成 ,如果异步执行失败 ,则返回异常;
             */
            channel.closeFuture().sync();
        } catch (InterruptedException e) {

            e.printStackTrace();

        }finally {

            off();
        }

    }

    @Override
    public void off() {
        if(boss !=null){
            boss.shutdownGracefully();
        }

        if(works!=null){
            works.shutdownGracefully();
        }
        if(channel !=null){
            channel.close();
        }
    }
}

WorksChannelInitializer



@Slf4j
public class WorksChannelInitializer  extends ChannelInitializer<SocketChannel> {

    /**
     *   创建处理网络事件的ChannelPipeline和handler,
     *   网络时间以流的形式在其中流转,handler完成多数的功能定制:比如编解码(粘包 拆包) SSl安全认证,
     *   https://blog.csdn.net/jinxyan/article/details/89712997
     */
    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        pipeline.addLast(new StringEncoder());
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new WorksChannelHandler());
    }

    /*
     * 如果是 proto
     *      final ChannelPipeline pipeline = socketChannel.pipeline();
     *      pipeline.addLast(new ProtobufVarint32FrameDecoder());
     *      pipeline.addLast(new ProtobufDecoder(Proto.Message.getDefaultInstance()));
     *      pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
     *      pipeline.addLast(new ProtobufEncoder());
     *      pipeline.addLast(new NettyServerHandler());
     */
}

WorksChannelHandler


@Slf4j
public class WorksChannelHandler extends SimpleChannelInboundHandler<String> {


    /**
     * 用来存储会话
     */
    private static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);



    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        final Channel channel = ctx.channel();

        log.info("【{}】连接到服务器",ctx.channel().id());

    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext,String msg) throws Exception {
        log.info("【{}】:{}",channelHandlerContext.channel().id(), JSON.toJSONString(msg));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("[{}]断开来连接",ctx.channel().id())  ;
    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("【{}】出现异常",ctx.channel().id());
        cause.printStackTrace();
        ctx.close();
    }



}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nier6088

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值