Netty---入门demo

demo1

简单的一个服务器实现,访问该服务器,返回一个"hello netty" 到网页

1.启动类

public class HelloServer {
    public static void main(String[] args) throws Exception{
        EventLoopGroup boosGroup=new NioEventLoopGroup();
        EventLoopGroup workerGroup =new NioEventLoopGroup();
        try{
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(boosGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HelloServerInitializer());
            ChannelFuture channelFuture=bootstrap.bind(8088).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            boosGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

初始化

public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        //通过SockerChannel 去获得对应的管道
        ChannelPipeline pipeline= socketChannel.pipeline();
        pipeline.addLast("HttpServerCodec",new HttpServerCodec());
        pipeline.addLast("customHandler",new CustomerHandler());
    }
}

处理类

public class CustomerHandler extends SimpleChannelInboundHandler<HttpObject> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        Channel channel=ctx.channel();
        if(msg instanceof HttpRequest){
            System.out.println(channel.remoteAddress());
            ByteBuf content=Unpooled.copiedBuffer("hello ",CharsetUtil.UTF_8);
            FullHttpResponse response=new DefaultFullHttpResponse(HttpVersion.HTTP_1_0,
                    HttpResponseStatus.OK,content);
            response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());
            ctx.writeAndFlush(response);
        }
    }
}

demo2

使用netty实现简单的聊天长连接(websocket)

启动类

public class WSServer {
    public static void main(String[] args) throws Exception {
        //先写两个主从线程组
        EventLoopGroup MainGroup=new NioEventLoopGroup();
        EventLoopGroup subGroup=new NioEventLoopGroup();
        try {
            //启动类
            ServerBootstrap bootstrap = new ServerBootstrap();
            //绑定
            bootstrap.group(MainGroup,subGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new WSServerInitialzer());
            //开启启动接口
            ChannelFuture channelFuture=bootstrap.bind(8088).sync();
            channelFuture.channel().closeFuture().sync();
            //关闭
        }finally {
            MainGroup.shutdownGracefully();
            subGroup.shutdownGracefully();
        }
    }
}

初始化

public class WSServerInitialzer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        //获得管道
        ChannelPipeline channelPipeline=socketChannel.pipeline();
        //对管道进行handler绑定,类似拦截器链
        //1.基于http协议的 解码器
        channelPipeline.addLast(new HttpServerCodec());
        //2.对大数据流的支持
        channelPipeline.addLast(new ChunkedWriteHandler());
        //3.对httpMessage的聚合(都会使用的)
        channelPipeline.addLast(new HttpObjectAggregator(1024*64));
        //httpWebSocket支持,长连接
        channelPipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        channelPipeline.addLast(new ChatHandler());
    }
}

处理类

public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    //客户端
    private static ChannelGroup clients=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //获取传过来的消息
        String content=msg.text();
        System.out.println("接收到:"+content);
        //返回客户端消息
        clients.writeAndFlush(new TextWebSocketFrame("[服务器在]"+ LocalDateTime.now()+"接受到消息,消息为:"+content));
    }
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        clients.add(ctx.channel());
    }
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户但断开,channle对应的长id为:"+ctx.channel().id().asLongText());
        System.out.println("客户端断开,channel对应的短id为:"+ctx.channel().id().asShortText());
    }
}

demo3 

官方写法

public class NettyDiscardServer {
    private  int serverPort=8080;
    ServerBootstrap b=new ServerBootstrap();
    public NettyDiscardServer(int port){
        this.serverPort=port;
    }
    public void runServer(){
        //创建反应器线程组
        EventLoopGroup bossLoopGroup=new NioEventLoopGroup(1);
        EventLoopGroup workerLoopGroup=new NioEventLoopGroup();
        try{
            //1 设置反应器线程组
            b.group(bossLoopGroup,workerLoopGroup);
            //2 设置nio类型的通道
            b.channel(NioServerSocketChannel.class);
            //3 设置监听端口
            b.localAddress(serverPort);
            //4 设置通道的参数
            b.option(ChannelOption.SO_KEEPALIVE,true);
            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            //5 装配子通道流水线
            b.childHandler(new ChannelInitializer<SocketChannel>() {
                protected void initChannel(SocketChannel ch){
                    ch.pipeline().addLast(new NettyDiscardHandler());
                }
            });
            //6 开始绑定服务器,通过调用sync同步方法阻塞直到绑定成功
            ChannelFuture channelFuture=b.bind().sync();
            //7 等待通道关闭的异步任务结束
            ChannelFuture closeFuture =channelFuture.channel().closeFuture();
            closeFuture.sync();
            //8 关闭EventLoopGroup
            workerLoopGroup.shutdownGracefully();
            bossLoopGroup.shutdownGracefully();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

    业务处理器:NettyDiscardHandler

public class NettyDiscardHandler extends ChannelInboundHandlerAdapter {
    public void channelRead(ChannelHandlerContext ctx,Object msg)throws Exception{
        ByteBuf in=(ByteBuf) msg;
        while(in.isReadable())
            System.out.print((char)in.readByte());
    }
}

    Reactor反应器作用:进行一个IO事件的select查询和dispatch分发(调用对应的handler)。

    应用场景不同,用到的反应器也不相同,对于NIO通信,对于的反应器类型:NioEventLoopGroup

    上面使用了两个反应器,一个是负责IO事件的监听,一个是负责传输通道的IO事件的处理。

    ServerBootstrap是一个服务启动类,它的职责就是组装集成器,将不同的Netty组件组装起来。

这里产生一个新的概念:入站和出战;简单的来说,入站就是输入的意思,出战就是输出的意思。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值