HTTP/HTTPS 是最常见的一种协议,这节主要是看一下 Netty 提供的 ChannelHaandler。

一、HTTP Decoder,Encoder 和 Codec

  HTTP 是请求-响应模式,客户端发送一个 HTTP 请求,服务就响应此请求。

  HttpRequest 包格式如下:

  

  1. 包头
  2. 数据部分,后续可以有多个 HttpContent 部分
  3. 包尾,标记 request 包结束,同时可能包含头的尾部信息
  4. 完整的 HTTP request

  HttpResponce 包格式如下:

  

  1. 包头
  2. 数据部分,后续可以有多个 HttpContent 部分
  3. 包尾,标记 responce 包结束,同时可能包含头的尾部信息
  4. 完整的 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 协议:

  

  1. Client(HTTP)与 Server 通讯
  2. Server(HTTP)与 Client 通讯
  3. Client 通过 HTTP(s) 来进行 WebSocket 握手,并等待确认
  4. 连接协议升级至 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应用的更多相关文章

  1. Netty入门教程——认识Netty

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...

  2. Netty入门教程:Netty拆包粘包技术讲解

    Netty编解码技术是什么意思呢?所谓的编解码技术,说白了就是java序列化技术.序列化有两个目的: 1.进行网络传输2.对象持久化 虽然我们可以使用java进行序列化,Netty去传输.但是java ...

  3. 深入了解Netty【六】Netty工作原理

    引言 前面学习了NIO与零拷贝.IO多路复用模型.Reactor主从模型. 服务器基于IO模型管理连接,获取输入数据,又基于线程模型,处理请求. 下面来学习Netty的具体应用. 1.Netty线程模 ...

  4. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  5. Netty入门与实战教程总结分享

    前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...

  6. (入门篇 NettyNIO开发指南)第三章-Netty入门应用

    作为Netty的第一个应用程序,我们依然以第2章的时间服务器为例进行开发,通过Netty版本的时间服务报的开发,让初学者尽快学到如何搭建Netty开发环境和!运行Netty应用程序. 如果你已经熟悉N ...

  7. netty 入门(一)

    netty Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更确切的讲是一个组件,没有那么复杂. 例子 一  Discard服务器端 我们 ...

  8. Netty入门

    一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...

  9. 高性能NIO框架Netty入门篇

    http://cxytiandi.com/blog/detail/17345 Netty介绍 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具 ...

  10. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

随机推荐

  1. C#常见几道面试题

    首先碰到的是这样的一首题目:计算数组{1,1,2,3,5,8.......} 第30位值,不用递归,我写出了以下这样的代码: static void Main(string[] args) { ]; ...

  2. 自己写一个java的mvc框架吧(四)

    自己写一个mvc框架吧(四) 写一个请求的入口,以及初始化框架 上一章写了获取方法的入参,并根据入参的参数类型进行数据转换.这时候,我们已经具备了通过反射调用方法的一切必要条件.现在我们缺少一个htt ...

  3. Outlook2013怎样自动答复电子邮件

    工具/原料 office2013或outlook2013 百度经验:jingyan.baidu.com 方法/步骤 1 首先我们创建自己的答复邮件.打开outlook2013,单击“开始”>“新 ...

  4. Django REST framework基础:版本、认证、权限、限制

    1  认证.权限和限制 2  认证 2.1  自定义Token认证 2.1.1  表 2.1.2  定义一个登录视图: 2.1.3  定义一个认证类 2.1.4  视图级别认证 2.1.5  全局级别 ...

  5. JS 闭包 p5

    终于到闭包了,写了一晚上,好激动: 首先闭包,个人是这样理解的(比较好记):闭包是一种能力,是一种可以访问内部函数作用域的能力或者说是一种行使权力,一旦你拥有这个能力,你将可以访问内部函数的作用域.

  6. enum 的使用方法(java)

    作者QQ:1095737364    QQ群:123300273     欢迎加入! enum很像特殊的class,实际上enum声明定义的类型就是一个类.而这些类都是类库中Enum类的子类(java ...

  7. 如何用JS获取页面上的所有标签

    最近忙的一匹,忙着大保健,都来不及写博客,今天特意抽出点时间来写一写 前两天看到一个题,是问如何从页面上获取所有的标签的并查看他们的数量,感觉还是有点意思的,所以给大家来搞一下子 我们先来捋捋思路,那 ...

  8. 【读书笔记】iOS-网络-解析响应负载

    Web Service可以通过多种格式返回结构化数据, 不过大多数时候使用的是XML与JSON.也可以让应用只接收HTML结构的数据.实现了这些Web Service或是接收HTML文档的应用必须能解 ...

  9. VC工程从Win32环境往Win64环境迁移的经验总结

    作者:朱金灿 来源:http://blog.csdn.net/clever101 首先需要安装Win64的开发环境,具体参考: VS 2008的64位编译环境的安装和使用 其次在工程属性设置中作如下修 ...

  10. SD从零开始41-44

    [原创] SD从零开始41 科目确定(Account determination) 使用科目确定Using Account Determination 你将需要在几个不同的领域确定将要记账的科目: 用 ...