美文网首页
Nettty入门实例

Nettty入门实例

作者: xbmchina | 来源:发表于2018-12-18 23:03 被阅读0次

步骤

  • 构建一对主从线程组
  • 定义服务器启动类
  • 为服务设置Channel
  • 设置处理从线程池的Handler初始化器
  • 监听启动和关闭服务器

代码

入口类:HelloServer

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class HelloServer {


    public static void main(String[] args) throws InterruptedException {
        //定义一对线程组
        //主线程组,用于接受客户端的连接,但是不做任何处理,跟老板一样,不做事
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //从线程组,老板线程组会把任务丢给他,让手下线程组做任务
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            //netty服务器创建,ServerBootstrap是一个启动类
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)//设置主从线程组
                    .channel(NioServerSocketChannel.class)//设置nio的双向通道
                    .childHandler(new HelloServerInitlializer());//子处理器,用于处理workerGroup
           //启动server,并且设置8888为启动的端口号,同时启动方式为同步
            ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();

            //监听关闭的channel,设置位同步方式。
            channelFuture.channel().closeFuture().sync();

        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
}

初始化channel器
图解:channel的初始化器的作用。

channel的初始化器.png

代码


import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;

/**
 * 初始化器,channel注册后,会执行里面的对应的初始化方法。
 */
public class HelloServerInitlializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {

        //通过socketChannel获得对应的管道
        ChannelPipeline pipeline = socketChannel.pipeline();

        //通过管道,添加handler
        // HttpServerCodec 当请求到服务端,我们需要做解码,响应到客户端需要做编码
        pipeline.addLast("HttpServerCodec",new HttpServerCodec());

        //添加的自定义handler
        pipeline.addLast("myHandler",new MyHandler());
    }
}

自定义Handler


import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

/**
 * 自定义的handler
 * SimpleChannelInboundHandler: 相当于队列入栈。
 */
public class MyHandler extends SimpleChannelInboundHandler<HttpObject> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {

        //获取channel
        Channel channel = ctx.channel();

        if (msg instanceof HttpRequest) {

            //显示客户端远程地址
            System.out.println(channel.remoteAddress());

            //定义发送的数据消息
            ByteBuf content = Unpooled.copiedBuffer("hello sb!", CharsetUtil.UTF_8);

            //构建一个http response
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
            //设置类型和长度
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());

            ctx.writeAndFlush(response);
        }


    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
        System.out.println("channel 注册。。。");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
        System.out.println("channel 移除。。。");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        System.out.println("channel 激活。。。");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);

        System.out.println("channel 不活跃。。。");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);

        System.out.println("channel 读取完成。。。");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);

        System.out.println("channel 用户事件触发。。。");
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        super.channelWritabilityChanged(ctx);

        System.out.println("channel 可写可更改。。。");
    }

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

        System.out.println("channel 捕获异常了。。。");
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);

        System.out.println("channel handler添加。。。");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        System.out.println("channel handler移除。。。");
    }
}

相关文章

网友评论

      本文标题:Nettty入门实例

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