Netty新手入门 – Hello Netty

一、什么是Netty?

Netty是一个提供了易于使用的api的客户端/服务器框架,Netyy的底层使用的是Nio(非阻塞io)零拷贝传输快并发高

二、Netty的线程模型

Netty的线程模型分别为 单线程,多线程,主从线程。 官方推荐的是 让我们使用主从线程

三、Netty之Hello Netty

3.1添加netty依赖

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.50.Final</version>
</dependency>

3.2在启动类中加入以下代码

import com.example.netty.nettydemo.config.HelloServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 *  实现客户端发送一个请求 ,服务器会返回 hello netty
 */
@SpringBootApplication
public class NettydemoApplication {

    public static void main(String[] args) throws InterruptedException {

        //定义一对线程组
        //主线程组,用于接受客户端的连接,但是不做任何处理,跟老板一样,不做事
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        //从线程组,老板线程组会把任务丢给他,让手下线程组去做任务
        NioEventLoopGroup workGroup = new NioEventLoopGroup();

        try {
            //netty服务器的创建,ServerBootStrap是一个启动类
            ServerBootstrap bootstrap = new ServerBootstrap();
            //设置主从线程组
            bootstrap.group(boosGroup,workGroup)
                    //设置NIO的双向通道
                    .channel(NioServerSocketChannel.class)
                    //字处理器,用于处理 workGroup
                    .childHandler(new HelloServerInitializer());

            //启动server,并且设置8088为启动的端口号,同时启动方式为同步
            ChannelFuture channelFuture = bootstrap.bind(8088).sync();
            //监听关闭的channel设置为同步
            channelFuture.channel().closeFuture().sync();
        }finally {
            //优雅的关闭 netty开启的线程连接
            boosGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }
        SpringApplication.run(NettydemoApplication.class, args);
    }



}

3.3创建字处理器

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

/**
 * 初始化器,channel注册后,会执行里面的相应的初始化方法
 * @author 风行烈
 * @version 1.0
 * @date 2020/8/26 17:09
 */
public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {


    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        //通过SocketChannel去获取对应的管道
        ChannelPipeline pipeline = channel.pipeline();
        //通过管道,添加handler
        //HttpServerCodes 是netty提供的助手类,可以理解拦截器
        //当请求到服务端  我们需要做编解码 ,响应到客户端做编码,在服务端做解码
        pipeline.addLast("HttpServerCodec",new HttpServerCodec());
        //添加自定义的助手类,返回hello word
        pipeline.addLast("customHandler",new CustomHandler());
    }
}

3.4添加自定义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;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;

/**
 * 创建自定义助手类
 * @author 风行烈
 * @version 1.0
 * @date 2020/8/27 10:01
 */

/**
 * SimpleChannelInboundHandler:对于请求来讲,相当于入站
 */
@Slf4j
public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        //从一个上下文对象里面 获取当前的这个管道
        Channel channel = ctx.channel();

        if(msg instanceof HttpRequest)
        {
            //获取客户端的远程地址
            log.info("客户端的远程地址:{}",channel.remoteAddress());

            //通过缓冲区发送数据
            ByteBuf word = Unpooled.copiedBuffer("Hello word", CharsetUtil.UTF_8);

            //发送到客户端消息
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, word);


            //设置发送给客户端的消息的类型 可以设置为 文本类型 也可以设置为图片类型  或者返回的json类型
            response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
            //设置发送给客户端的消息长度
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH,word.readableBytes());

            //需要把我们的内容发送给客户端
            ctx.writeAndFlush(response);
        }

    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channel-------------------------注册");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channel-----------------------移除");
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("channel---------------------------活跃");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("channel----------------------------不活跃");
        super.channelInactive(ctx);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("channel------------------读取完毕");
        super.channelReadComplete(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.info("channel用户触发");
        super.userEventTriggered(ctx, evt);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        log.info("channel可写更改");
        super.channelWritabilityChanged(ctx);
    }

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

3.5访问监听的8088端口
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

往日时光--

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

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

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

打赏作者

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

抵扣说明:

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

余额充值