用Idea搭建简单的Netty服务器

本文使用netty自定义了一个http协议的服务器。

1.创建一个maven项目,在pom.xml文件中导入依赖并刷新

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-all</artifactId>
      <version>4.1.16.Final</version>
    </dependency>

2.搭建一个Netty服务器,我们只需要两个类——一个是启动类,负责启动(BootStrap)和main方法;一个是ChannelHandler,负责具体的业务逻辑。

启动类:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;

import java.util.Date;

/**
 * Created by RoyDeng on 20/03/22.
 */
public class HttpServer {

    private final static int port = 8080;


    public static void main(String[] args) throws Exception {
        System.out.println(new Date().toLocaleString()+"netty服务器启动了");
        start();
    }

    public static void start() throws Exception {
        //ServerBootstrap作为一个启动辅助类,通过他可以很方便的创建一个Netty服务端
        ServerBootstrap b = new ServerBootstrap();
        //创建线程池
        NioEventLoopGroup group = new NioEventLoopGroup();
        b.group(group)
                //指定使用NioServerSocketChannel来处理连接请求,放射生成一个channel连接
                .channel(NioServerSocketChannel.class)
                //配置handler和childHandler,数据处理器
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch)
                            throws Exception {
                        System.out.println("initChannel ch:" + ch);
                        ch.pipeline()
                                // HttpRequestDecoder,用于解码request
                                .addLast("decoder", new HttpRequestDecoder()) 
                                // HttpResponseEncoder,用于编码response  
                                .addLast("encoder", new HttpResponseEncoder()) 
                                //aggregator消息聚合器,参数含义是消息合并的数据大小,如此代表聚合的消息内容长度不超过512kb
                                .addLast("aggregator", new HttpObjectAggregator(512 * 1024))
                                //添加我们自己的处理接口
                                .addLast("handler", new HttpHandler());        // 4
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128) // 配置TCP参数
                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE);//
        //启动服务器
        b.bind(port).sync();
    }
}

handler线程处理类

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.AsciiString;

import java.util.Date;

/**
 * Handler需要声明泛型为<FullHttpRequest>,声明之后,只有msg为FullHttpRequest的消息才能进来
 */
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    private AsciiString contentType = HttpHeaderValues.TEXT_PLAIN;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
        System.out.println(new Date().toLocaleString()+"class:" + msg.getClass().getName());
        /*
        生成response,使用的FullHttpResponse,同FullHttpRequest类似,
        通过这个我们就不用将response拆分成多个channel返回给请求端了
        */
        DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                // 响应内容:test --> 使用平台的默认字符集将字符串编码为 byte 序列,存为新的 byte 数组中
                Unpooled.wrappedBuffer("test".getBytes()));

        HttpHeaders heads = response.headers();
        //定义响应头的content_type、content_length、connection:keep_alive
        heads.add(HttpHeaderNames.CONTENT_TYPE, contentType + "; charset=UTF-8");
        heads.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); // 3
        heads.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);

        ctx.write(response);
    }
    //读取完成,输出缓冲流
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println(new Date().toLocaleString()+"channelReadComplete");
        super.channelReadComplete(ctx);
        //清空连接数据
        ctx.flush();
    }

    //异常捕获
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("exceptionCaught");
        if(null != cause) cause.printStackTrace();
        if(null != ctx) ctx.close();
    }
}

运行,浏览器输入:http://localhost:8080

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值