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中文 ...
随机推荐
- Extjs 项目中常用的小技巧,也许你用得着(4)---Extjs 中的cookie设置
1.ExtJs设置cookie两种方式 其一:设置cookie如下 saveacct=isForm.getForm().findField('itemselector').getValue(); Ex ...
- 爬虫、网页分析解析辅助工具 Xpath-helper
每一个写爬虫.或者是做网页分析的人,相信都会因为在定位.获取xpath路径上花费大量的时间,甚至有时候当爬虫框架成熟之后,基本上主要的时间都花费在了页面的解析上.在没有这些辅助工具的日子里,我们只能通 ...
- 第16课-数据库开发及ado.net-数据库SQl,创建数据库和表,增删改语句,约束,top和Distinct,聚合函数介绍
第16课-数据库开发及ado.net 数据库SQl,创建数据库和表,增删改语句,约束,top和Distinct,聚合函数介绍 SQL语句入门(脚本.命令) SQL全名是结构化查询语言(Structur ...
- Docker入门及基本指令
Docker概念 Docker就相当于一个Github账号,不过最开始的工程不能自己建立,要从DockerHub这个中央仓库pull过来,这个工程Docker称之为image,这个image竟然是个l ...
- How to write a professional email?
Advantages and Disadvantages of Email communication compared with Face-To-Face communication: Emai ...
- Liunx下配置网络
1.首先查看一下自己的网络 ifconfig 我查看之后发现....没有eth0 ok,现在去 /etc/sysconfig/network-scripts 目录中查看是否有 ifcfg-et0 文件 ...
- Python 初识网络
一. C/S架构:客户端(client)/服务端(server)架构 B/S架构:浏览器(browser) / 服务端(server)架构 软件cs架构: 浏览器,qq,微信等等 硬件cs架构:打印机 ...
- 高性能JavaScript(算法和流程控制)
在大多与编程语言中,代码的执行时间大部分消耗在循环中,是提升性能必须关注的要点之一 循环的类型 for循环(它由四部分组成:初始化.前测条件.后执行体.循环体.) for(var i = 0; i & ...
- Python笔记(四):异常处理机制与 open()
(一) 异常处理机制概述 就像日常生活中会遇到各种意外情况一样(例如:你可能考虑过如果中了500w该怎么做),代码运行过程中也会遇到这种意外情况,python提供了这么一种机制,处理意外情况(就像如 ...
- Git执行过程中出现问题及解决方法
not-fast-forward https://help.github.com/articles/dealing-with-non-fast-forward-errors/