0
点赞
收藏
分享

微信扫一扫

12-Netty 高性能架构设计-基于Netty开发HTTP服务

眼君 2022-02-28 阅读 50


快速入门实例-HTTP 服务


  1. D实例要求:使用IDEA创建Netty项目
  2. Netty服务器在6668端口监听,浏览器发出请求“​​http://localhost:6668/​​


  3. 服务器可以回复消息给客户端“Hello!我是服务器5”,并对特定请求资源进行过滤
  4. 目的:Netty可以做Http服务开发,并且理解Handler实例和客户端及其请求的关系


看老师代码演示

新建HttpServer

package com.dance.netty.netty.http;

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

/**
* HTTP 服务器
*/
public class HttpServer {

public static void main(String[] args) {

NioEventLoopGroup boosGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();

try {
ServerBootstrap serverBootstrap = new ServerBootstrap();

serverBootstrap.group(boosGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new HttpServerInitializer());

ChannelFuture sync = serverBootstrap.bind("127.0.0.1",80).sync();

sync.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
boosGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}

}

}


新建HttpServerInitializer

package com.dance.netty.netty.http;

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

/**
* 通道初始化
*/
public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {

@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 向管道加入处理器
ChannelPipeline pipeline = socketChannel.pipeline();
// 加入一个Netty提供的 HttpServerCodec codec => [coder - decoder]
/*
HttpServerCodec 是Netty提供的处理HTTP的
*/
pipeline.addLast("MyHttpServer", new HttpServerCodec());

// 添加自己的处理器
pipeline.addLast("MyHandler", new HttpServerHandler());
}
}


新建HttpServerHandler

package com.dance.netty.netty.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;

import java.nio.charset.StandardCharsets;

/**
* 管道处理器
* SimpleChannelInboundHandler 继承了 ChannelInboundHandlerAdapter
* HttpObject 客户端和服务器相互通讯的数据定义
*/
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {


/**
* 读取客户端数据
* @param channelHandlerContext 上下文对象
* @param msg httpObject对象
* @throws Exception 异常
*/
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject msg) throws Exception {
// 判断是不是HttpRequest
if(msg instanceof HttpRequest){
System.out.println("msg type is " + msg.getClass());
System.out.println("client address is " + channelHandlerContext.channel().remoteAddress());

// 回复信息给浏览器 [HTTP协议]
ByteBuf byteBuf = Unpooled.copiedBuffer("Hello 我是服务器~", StandardCharsets.UTF_8);

// 构造一个HTTP的响应, 即 HttpResponse
DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);

// 设置响应信息
httpResponse.headers()
.set(HttpHeaderNames.CONTENT_TYPE, "text/plain;Charset=UTF-8")
.set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());

channelHandlerContext.writeAndFlush(httpResponse);
}
}
}


测试

12-Netty 高性能架构设计-基于Netty开发HTTP服务_.net

这里存在一个问题,那就是端口问题,之前是6668 chrome 访问直接被阻止

12-Netty 高性能架构设计-基于Netty开发HTTP服务_.net_02

还有就是,在返回的类型中需要设置字符编码.不然会乱码

// 设置响应信息
httpResponse.headers()
.set(HttpHeaderNames.CONTENT_TYPE, "text/plain;Charset=UTF-8")
.set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());


12-Netty 高性能架构设计-基于Netty开发HTTP服务_.net_03

但是还是有一个问题的, 我访问了一次,但是控制台却显示的是两次

12-Netty 高性能架构设计-基于Netty开发HTTP服务_bootstrap_04

12-Netty 高性能架构设计-基于Netty开发HTTP服务_.net_05

原因是应为在浏览器加载资源 的时候,同时请求了页面浏览器角标

12-Netty 高性能架构设计-基于Netty开发HTTP服务_服务器_06

就是这个东西

修改HttpServerHandler

package com.dance.netty.netty.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;

import java.nio.charset.StandardCharsets;

/**
* 管道处理器
* SimpleChannelInboundHandler 继承了 ChannelInboundHandlerAdapter
* HttpObject 客户端和服务器相互通讯的数据定义
*/
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {


/**
* 读取客户端数据
* @param channelHandlerContext 上下文对象
* @param msg httpObject对象
* @throws Exception 异常
*/
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject msg) throws Exception {
// 判断是不是HttpRequest
if(msg instanceof HttpRequest){

// 进行资源过滤
String uri = ((HttpRequest) msg).uri();
// 如果是图标直接结束
if(uri.endsWith("favicon.ico")){
System.out.println("request is favicon.ico, no result");
return;
}

.............
}
}
}


重启后测试

12-Netty 高性能架构设计-基于Netty开发HTTP服务_.net_07

可以看到角标被过滤了


举报

相关推荐

0 条评论