当前位置: 首页 > 后端技术 > Java

netty系列之-轻轻松松搭个支持中文的服务器

时间:2023-04-02 10:32:01 Java

Netty系列:轻松搭建一个支持中文的服务器这篇文章,netty能做什么?今天就让我们使用netty来简单搭建一个支持中文的服务器,展示一下netty的强大吧。Netty的HTTP支持我们今天搭建的服务器是支持HTTP1.1的服务器。在netty中搭建服务器就像盖房子。找到合适的工具可以事半功倍。那么搭建HTTP之家,netty提供了什么样的工具呢?在说明netty对HTTP的支持之前,我们先来看看HTTP版本的发展情况。HTTP的全称是HypertextTransferProtocol,是1989年万维网发展之后出现的标准协议,用于在WWW上传输数据。HTTP/1.1是1997年在原有HTTP协议的基础上进行的补充和优化,到2015年,为了满足快速发送的Web应用和现代浏览器的需求,开发了新的HTTP/2协议,主要在以下方面进行了优化移动浏览器、延迟处理、图像处理和视频处理。基本上现代浏览器都支持HTTP/2协议,但仍然有很多应用程序使用旧的HTTP/1.1协议。Netty为HTTP2和HTTP1提供了不同的支持包。对HTTP1的支持包叫做netty-codec-http,对HTTP2支持的包叫做netty-codec-http2。本文将讲解netty对HTTP1的支持,后续文章会继续介绍HTTP2。netty-codec-http为HTTP提供了一些非常有用的包装器。首先是HTTP中表示传输对象的类HttpObject,表示传输中的所有对象。继承该类的对象有两个非常重要的对象,即HttpMessage和HttpContent。HttpMessage可能和我想象的不太一样。它实际上只包含两部分,即HttpVersion和HttpHeaders,但不包含任何内容。publicinterfaceHttpMessageextendsHttpObject{HttpVersionprotocolVersion();HttpMessagesetProtocolVersion(HttpVersion版本);HttpHeadersheaders();}这里HttpVersion只支持HTTP/1.0和HTTP/1.1协议。HttpHeaders是对HTTP请求中的header对象的封装。HttpMessage的子类是HttpRequest和HttpResponse,所以这两个类本身不携带请求内容。具体请求的内容在HttpContent中,HttpContent继承自ByteBufHolder,也就是说可以包含ByteBuf内容信息。HttpContent真正的实现类是DefaultFullHttpRequest和DefaultFullHttpResponse,包含了HTTP头和HTTP请求响应内容信息。那么问题来了,为什么要把HTTP头和HTTP内容分开呢?这就涉及到了HTTP1.1中消息传输中的压缩机制。为了提高传输效率,一般来说,对象消息在传输过程中都会被压缩。但是对于HTTP1.1来说,header的内容是不能压缩的,只能压缩content部分,所以需要区别对待。netty中使用HTTP的原理我们知道netty底层是在客户端和服务端之间建立一个通道,通过通道传输ByteBuf消息。那么netty是如何支持HTTP请求的呢?客户端向服务器发送HTTP请求后,服务器需要使用解码器将接收到的数据解码为应用程序可以使用的各种HttpObject对象,以便在应用程序中进行解析。Netty提供了HttpResponseEncoder和HttpRequestDecoder类来编码和解码HTTP消息。如果不想使用两个类分别进行编码和解码,netty也提供了HttpServerCodec类进行编码和解码。这个类包括了HttpRequestDecoder和HttpResponseEncoder的工作,可以同时用于编码和解码。100(Continue)Status在HTTP中有一个特有的功能叫做100(Continue)Status,意思是当客户端不确定服务器是否会收到请求时,可以先发送一个请求头,加上一个“100-continue”字段,但请求正文尚未发送。在收到服务器的响应之前,不会发送请求正文。为了处理这个请求,netty提供了一个HttpServerExpectContinueHandler对象来处理100Status的情况。当然,如果你的客户端没有这样的请求,你可以直接使用HttpObjectAggregator将HttpMessage和HttpContent组合成FullHttpRequest或FullHttpResponse。为netty搭建一个http服务器通过上面的工作,我们就可以使用netty来搭建一个http服务器了。最关键的一点是在HttpRequestServerInitializer中添加相应的codec和自定义handler。publicvoidinitChannel(SocketChannelch){ChannelPipelinep=ch.pipeline();p.addLast(新的HttpServerCodec());p.addLast(新的HttpServerExpectContinueHandler());p.addLast(新的HttpRequestServerHandler());在定义的处理程序中,我们需要实现一个功能,即当收到客户端的请求时,我们需要向客户端返回一个欢迎信息。先将获取到的HttpObject转化为HttpRequest对象,然后根据request对象构造DefaultFullHttpResponse对象,然后设置response对象的header,最后将对象写入channel。对应的关键字代码如下:privatestaticfinalbyte[]CONTENT="欢迎来到www.flydean.com!".getBytes(StandardCharsets.UTF_8);publicvoidchannelRead0(ChannelHandlerContextctx,HttpObjectmsg){if(msginstanceofHttpRequest){HttpRequestreq=(HttpRequest)msg??;布尔keepAlive=HttpUtil.isKeepAlive(req);FullHttpResponseresponse=newDefaultFullHttpResponse(req.protocolVersion(),OK,Unpooled.wrappedBuffer(CONTENT));response.headers()//.set(CONTENT_TYPE,TEXT_PLAIN).set(CONTENT_TYPE,"text/plain;charset=utf-8").setInt(CONTENT_LENGTH,response.content().readableBytes());if(keepAlive){if(!req.protocolVersion().isKeepAliveDefault()){//设置headerconnection=keep-aliveresponse.headers().set(CONNECTION,KEEP_ALIVE);}}else{//如果keepAlive为假,设置headerconnection=closeresponse.headers().set(CONNECTION,CLOSE);}ChannelFuturef=ctx.write(response);如果(!keepAlive){f。添加监听器(ChannelFutureListener.CLOSE);上面关键代码中,CONTENT中包含一个中文字符串,我们使用getBytes将其转换为UTF-8编码的字节数组,那么如果我们想让客户端正确识别UTF-8编码,就需要设置响应头中的内容类型文件为:“text/plain;charset=utf-8”。最后,使用以下代码启动服务器://serverconfigurationEventLoopGroupbossGroup=newNioEventLoopGroup(1);EventLoopGroupworkerGroup=newNioEventLoopGroup();尝试{ServerBootstrapb=newServerBootstrap();b.option(ChannelOption.SO_BACKLOG,1024);b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).handler(newLoggingHandler(LogLevel.INFO)).childHandler(newHttpRequestServerInitializer());通道ch=b.bind(PORT).sync()。渠道();log.info("请打开浏览器访问http://127.0.0.1:8000/");ch.closeFuture().sync();}最后{bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}总结现在,用浏览器访问你搭建的服务器地址,可以得到“Welcometowww.flydean.com!”。至此一个简单的netty服务器就完成了。本文示例可参考:learn-netty4本文已收录于http://www.flydean.com/19-netty-http-client-request/最通俗的解读,最深刻的干货,最简洁的教程,许多你不为人知的小技巧等你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!

最新推荐
猜你喜欢