Netty入门(八)构建Netty HTTP/HTTPS应用
HTTP/HTTPS 是最常见的一种协议,这节主要是看一下 Netty 提供的 ChannelHaandler。
一、HTTP Decoder,Encoder 和 Codec
HTTP 是请求-响应模式,客户端发送一个 HTTP 请求,服务就响应此请求。
HttpRequest 包格式如下:
- 包头
- 数据部分,后续可以有多个 HttpContent 部分
- 包尾,标记 request 包结束,同时可能包含头的尾部信息
- 完整的 HTTP request
HttpResponce 包格式如下:
- 包头
- 数据部分,后续可以有多个 HttpContent 部分
- 包尾,标记 responce 包结束,同时可能包含头的尾部信息
- 完整的 HTTP responce
下面是 Netty 提供的解码器和编码器用来处理上述的包信息:
所以,如果我们想要在应用程序中支持 HTTP,只需要添加正确的 ChannelHandler 到 ChannelPipeline 中即可:
public class HttpPipelineInitializer extends ChannelInitializer<Channel> {
private final boolean client; public HttpPipelineInitializer(boolean client) {
this.client = client;
} @Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
if(client) {
// 客户端需要解码服务器响应,编码客户端请求
pipeline.addLast("decoder", new HttpResponseDecoder());
pipeline.addLast("encoder", new HttpRequestEncoder());
} else {
// 服务端需要解码客户端请求,编码服务端响应
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
}
} }
二、HTTP 消息聚合
由于 HTTP 请求和响应消息部分可以由许多块组成,我们需要聚合它们形成完整的消息。Netty 提供了一个聚合器。如下为简单实现:
/**
* HTTP 消息聚合
* HttpObjectAggregator
*/
public class HttpAggregatorInitializer extends ChannelInitializer<Channel> {
private final boolean client; public HttpAggregatorInitializer(boolean client) {
this.client = client;
} @Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
if(client) {
// 客户端
pipeline.addLast("codec", new HttpClientCodec());
} else {
// 服务器
pipeline.addLast("codec", new HttpServerCodec());
}
// HTTP聚合,设置最大消息值为512KB
pipeline.addLast("aggegator", new HttpObjectAggregator(512 * 1024));
} }
三、HTTP 压缩
使用 HTTP 时建议压缩数据以减少传输流量,Netty 支持 “gzip”和“deflate”。简单实现如下:
/**
* HTTP 压缩
* HttpContentDecompressor 用于客户端解压缩
* HttpContentCompressor 用于服务器压缩
*/
public class HttpCompressorInitializer extends ChannelInitializer<Channel> {
private final boolean client; public HttpCompressorInitializer(boolean client) {
this.client = client;
} @Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
if(client) {
// 客户端
pipeline.addLast("codec", new HttpClientCodec());
// 解压缩,用于处理来自服务器的压缩内容
pipeline.addLast("decompressor", new HttpContentDecompressor());
} else {
// 服务端
pipeline.addLast("codec", new HttpServerCodec());
// 压缩,将要发送的消息压缩后再发出
pipeline.addLast("compressor", new HttpContentCompressor());
}
} }
四、使用 HTTPS
启动 HTTPS(比 HTTP 安全),只需添加 SslHandler。简单实现如下:
/**
* HTTPS
*/
public class HttpsCodecInitializer extends ChannelInitializer<Channel> {
private final SslContext context;
private final boolean client; public HttpsCodecInitializer(SslContext context, boolean client) {
this.context = context;
this.client = client;
} @Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
SSLEngine engine = context.newEngine(ch.alloc()); // 添加SslHandler以启用HTTPS
pipeline.addFirst("ssl", new SslHandler(engine));
if(client) {
// 客户端
pipeline.addLast("codec", new HttpClientCodec());
} else {
// 服务端
pipeline.addLast("codec", new HttpServerCodec());
}
} }
五、WebSocket
WebSocket 允许数据双向传输,而不需要请求-响应模式。当我们需要服务器主动向客户端发送消息,比如实时系统,WebSocket 就是一个不错的选择。下面是一个通用的 WebSocket 协议:
- Client(HTTP)与 Server 通讯
- Server(HTTP)与 Client 通讯
- Client 通过 HTTP(s) 来进行 WebSocket 握手,并等待确认
- 连接协议升级至 WebSocket
应用程序支持 WebSocket 只需要添加适当的客户端或服务器端 WebSocket ChannelHandler 到管道。这个类将处理 WebSocket 定义的信息类型,称为“帧”。帧类型可分为数据帧和控制帧,如下:
简单实现如下:
/**
* WebSocket
* WebSocketServerProtocolHandler 处理其他类型帧
* TextFrameHandler BinaryFrameHandler ContinuationFrameHandler
*/
public class WebSocketServerInitializer extends ChannelInitializer<Channel> { @Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(
new HttpServerCodec(),
new HttpObjectAggregator(65536), // HTTP 聚合
// 处理除指定Frame之外的其他类型帧,比如Ping,Pong,Close等
new WebSocketServerProtocolHandler("/websocket"),
new TextFrameHandler(),
new BinaryFrameHandler(),
new ContinuationFrameHandler());
} // Text Frame
public static final class TextFrameHandler
extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
// TODO Handle Text Frame
}
} // Binary Frame
public static final class BinaryFrameHandler
extends SimpleChannelInboundHandler<BinaryWebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, BinaryWebSocketFrame msg) throws Exception {
// TODO Handle Text Frame
}
} // Continuation Frame
public static final class ContinuationFrameHandler
extends SimpleChannelInboundHandler<ContinuationWebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ContinuationWebSocketFrame msg) throws Exception {
// TODO Handle Text Frame
}
}
}
Netty入门(八)构建Netty HTTP/HTTPS应用的更多相关文章
- Netty入门教程——认识Netty
什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...
- Netty入门教程:Netty拆包粘包技术讲解
Netty编解码技术是什么意思呢?所谓的编解码技术,说白了就是java序列化技术.序列化有两个目的: 1.进行网络传输2.对象持久化 虽然我们可以使用java进行序列化,Netty去传输.但是java ...
- 深入了解Netty【六】Netty工作原理
引言 前面学习了NIO与零拷贝.IO多路复用模型.Reactor主从模型. 服务器基于IO模型管理连接,获取输入数据,又基于线程模型,处理请求. 下面来学习Netty的具体应用. 1.Netty线程模 ...
- Java IO学习笔记八:Netty入门
作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...
- Netty入门与实战教程总结分享
前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...
- (入门篇 NettyNIO开发指南)第三章-Netty入门应用
作为Netty的第一个应用程序,我们依然以第2章的时间服务器为例进行开发,通过Netty版本的时间服务报的开发,让初学者尽快学到如何搭建Netty开发环境和!运行Netty应用程序. 如果你已经熟悉N ...
- netty 入门(一)
netty Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更确切的讲是一个组件,没有那么复杂. 例子 一 Discard服务器端 我们 ...
- Netty入门
一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...
- 高性能NIO框架Netty入门篇
http://cxytiandi.com/blog/detail/17345 Netty介绍 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具 ...
- Netty 系列(三)Netty 入门
Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...
随机推荐
- 一篇文章理清WebGL绘制流程
转自:https://www.jianshu.com/p/e3d8a244f3d9 目录 初始化WebGL环境 顶点着色器(Vertex Shader)与片元着色器(Fragment Shader) ...
- 4+1视图与UML对应关系
4+1视图模型概况 Kruchten 提出了一个"4+1"视图模型,从5个不同的视角包括包括逻辑试图.进程视图.物理视图.开发视图.场景视图来描述软件体系结构.每一个视图只 ...
- BOM(JavaScript高程笔记)
再次编辑于20160115 一.window对象 双重角色 JS访问浏览器窗口的接口 ECAMAscript规定的Global对象 1.全局作用域 所有在全局作用域中声明的变量.函数都会变成windo ...
- 用windows浏览器打开Linux的Jupyter notebook开发、调试示例
1.场景,在windows浏览器中打开Linux环境下的jupyter notebook.Jupyter notebook开启远程服务,Spark.python计算环境在Linux服务器中,而工作环境 ...
- SD从零开始31-32
SD从零开始31 包装(Packing) 装运材料Shipping Materials Shipping materials是用来包装或者运输货物的材料: 为了在系统中为outbound delive ...
- 禅道项目管理软件 为提交Bug页面设置bug必填字段
为提交Bug页面设置bug必填字段 by:授客 QQ:1033553122 测试环境: 禅道项目管理软件7.1.stable版本 注:仅适合windows版 步骤1.找到xampp\zentao\mo ...
- C语言中数据类型的本质
数据类型可以理解为固定内存大小的别名.比如int类型,就是表示占用4字节的内存. 1 数据类型的大小 用sizeof操作符获得数据类型的大小. 比如 int a[5]; sizeof(a)就可以得 ...
- Android逆向 Android平台虚拟机
一 Dalvik:是Google开发运行在Android平台的Java虚拟机, Android程序编译后会生成dex文件.Dalvik虚拟机下运行Java时,要将字节码通过即时编译器(just in ...
- Python笔记(十):正则表达式
正则表达式对比工具 https://pan.baidu.com/s/1XIPyF1vFSj5PACPx9zW8_g (一) 正则表达式符号和特殊字符 符号 说明 示例 | 或 re1|re2 ...
- window平台搭建Hudson服务器
1.1 环境 Microsoft Windows server 2008 x64 1.2 资源下载 TortoiseSVN-1.7.11.23600-x64-svn-1.7.8.msi h ...