Netty:透明地使用SPDY和HTTP
- 在Java中启用NPN以确定要使用的协议。
- 根据协商的协议,确定使用HTTP还是SPDY。
- 确保使用HTTP发送回正确的SPDY标头。
- 将NPN lib添加到引导路径
- 将SSL上下文连接到NPN Api
java -Xbootclasspath/p:<path_to_npn_boot_jar>
<dependency><groupId>io.netty</groupId><artifactId>netty</artifactId><version>3.4.1.Final</version></dependency><dependency><groupId>org.eclipse.jetty.npn</groupId><artifactId>npn-api</artifactId><version>8.1.2.v20120308</version></dependency>
package smartjava.netty.spdy;
import static org.jboss.netty.channel.Channels.pipeline;import java.io.FileInputStream;
import java.security.KeyStore;import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;import org.eclipse.jetty.npn.NextProtoNego;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.ssl.SslHandler;public class SPDYPipelineFactory implements ChannelPipelineFactory {private SSLContext context;public SPDYPipelineFactory() {try {KeyStore keystore = KeyStore.getInstance("JKS");keystore.load(new FileInputStream("src/main/resources/server.jks"),"secret".toCharArray());KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(keystore, "secret".toCharArray());context = SSLContext.getInstance("TLS");context.init(kmf.getKeyManagers(), null, null);} catch (Exception e) {e.printStackTrace();}}public ChannelPipeline getPipeline() throws Exception {// Create a default pipeline implementation.ChannelPipeline pipeline = pipeline();// Uncomment the following line if you want HTTPSSSLEngine engine = context.createSSLEngine();engine.setUseClientMode(false);NextProtoNego.put(engine, new SimpleServerProvider());NextProtoNego.debug = true;pipeline.addLast("ssl", new SslHandler(engine));pipeline.addLast("pipeLineSelector", new HttpOrSpdyHandler());return pipeline;}
}
public class SimpleServerProvider implements ServerProvider {private String selectedProtocol = null;public void unsupported() {//if unsupported, default to http/1.1selectedProtocol = "http/1.1";}public List<String> protocols() {return Arrays.asList("spdy/2","http/1.1");}public void protocolSelected(String protocol) {selectedProtocol = protocol;}public String getSelectedProtocol() { return selectedProtocol;}
}
- 当客户端不支持NPN时,将调用不受支持的操作。 在这种情况下,我们默认为HTTP。
- protocol()操作返回服务器支持的协议
- 服务器和客户端协商协议后,将调用protocolSelected操作
pipeline.addLast("ssl", new SslHandler(engine));
pipeline.addLast("pipeLineSelector", new HttpOrSpdyHandler());
public class HttpOrSpdyHandler implements ChannelUpstreamHandler {public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)throws Exception {// determine protocol typeSslHandler handler = ctx.getPipeline().get(SslHandler.class);SimpleServerProvider provider = (SimpleServerProvider) NextProtoNego.get(handler.getEngine());if ("spdy/2".equals(provider.getSelectedProtocol())) {ChannelPipeline pipeline = ctx.getPipeline();pipeline.addLast("decoder", new SpdyFrameDecoder());pipeline.addLast("spdy_encoder", new SpdyFrameEncoder());pipeline.addLast("spdy_session_handler", new SpdySessionHandler(true));pipeline.addLast("spdy_http_encoder", new SpdyHttpEncoder());// Max size of SPDY messages set to 1MBpipeline.addLast("spdy_http_decoder", new SpdyHttpDecoder(1024*1024)); pipeline.addLast("handler", new HttpRequestHandler());// remove this handler, and process the requests as spdypipeline.remove(this);ctx.sendUpstream(e);} else if ("http/1.1".equals(provider.getSelectedProtocol())) {ChannelPipeline pipeline = ctx.getPipeline();pipeline.addLast("decoder", new HttpRequestDecoder());pipeline.addLast("http_encoder", new HttpResponseEncoder());pipeline.addLast("handler", new HttpRequestHandler());// remove this handler, and process the requests as httppipeline.remove(this);ctx.sendUpstream(e);} else {// we're still in protocol negotiation, no need for any handlers// at this point.}}
}
- 没有协议 :可能尚未协商任何协议。 在那种情况下,我们没有做任何特别的事情,只需正常处理即可。
- 有一个http协议 :我们建立了一个处理程序链来处理HTTP请求。
- 有一个spdy协议 :我们建立了一个处理程序链来处理SPDY请求。
private final static String SPDY_STREAM_ID = = "X-SPDY-Stream-ID";private final static String SPDY_STREAM_PRIO = "X-SPDY-Stream-Priority";// in the writeResponse method addif (request.containsHeader(SPDY_STREAM_ID)) {response.addHeader(SPDY_STREAM_ID,request.getHeader(SPDY_STREAM_ID));// optional header for prioresponse.addHeader(SPDY_STREAM_PRIO,0);}
public class SPDYServer {public static void main(String[] args) {// bootstrap is used to configure and setup the serverServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool()));bootstrap.setPipelineFactory(new SPDYPipelineFactory());bootstrap.bind(new InetSocketAddress(8443));}
}
[S] NPN received for 68ce4f39[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
[S] NPN protocols [spdy/2, http/1.1] sent to client for 68ce4f39[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
[S] NPN received for 4b24e48f[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
[S] NPN protocols [spdy/2, http/1.1] sent to client for 4b24e48f[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
[S] NPN selected 'spdy/2' for 4b24e48f[SSLEngine[hostname=null port=-1] SSL_NULL_WITH_NULL_NULL]
jos@Joss-MacBook-Pro.local:~$ wget --no-check-certificate https://localhost:8443/thisIsATest
--2012-04-27 16:29:09-- https://localhost:8443/thisIsATest
Resolving localhost... ::1, 127.0.0.1, fe80::1
Connecting to localhost|::1|:8443... connected.
WARNING: cannot verify localhost's certificate, issued by `/C=NL/ST=NB/L=Waalwijk/O=smartjava/OU=smartjava/CN=localhost':Self-signed certificate encountered.
HTTP request sent, awaiting response... 200 OK
Length: 285
Saving to: `thisIsATest'100%[==================================================================================>] 285 --.-K/s in 0s 2012-04-27 16:29:09 (136 MB/s) - `thisIsATest' saved [285/285]jos@Joss-MacBook-Pro.local:~$ cat thisIsATest
WELCOME TO THE WILD WILD WEB SERVER
===================================
VERSION: HTTP/1.1
HOSTNAME: localhost:8443
REQUEST_URI: /thisIsATestHEADER: User-Agent = Wget/1.13.4 (darwin11.2.0)
HEADER: Accept = */*
HEADER: Host = localhost:8443
HEADER: Connection = Keep-Alivejos@Joss-MacBook-Pro.local:~$
翻译自: https://www.javacodegeeks.com/2012/05/netty-using-spdy-and-http-transparently.html
Netty:透明地使用SPDY和HTTP相关推荐
- Netty In Action中文版 - 第十二章:SPDY
Netty In Action中文版 - 第十二章:SPDY 本章我将不会直接翻译Netty In Action书中的原文,感觉原书中本章讲的很多废话,我翻译起来也吃力.所以,本章内容我会根据其他资料 ...
- SPDY:Google开发的下一代HTTP协议
SPDY(发音同"speedy"):Google开发的下一代HTTP协议 (解决HTTP协议的缺点,Wrapper模式) 概述 SPDY是Google宣布正在开发的下一代网络协议, ...
- 仿qq左滑删除listview_Java基于Swing和Netty仿QQ界面聊天小项目
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 来源:b ...
- 一文搞定7大流行后端框架:Spring、Netty、MyBatis、Hibernate、Dubbo...
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法:另一种定义认为,框架是可被应用开发者定制的应用骨架.前者是从应用方面而后者是从目的方面给出的定义. 可 ...
- Java基于Swing和Netty仿QQ界面聊天小项目
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:blog.csdn.net/weixin_44048 ...
- 从netty-example分析Netty组件
分析netty从源码开始 准备工作: 1.下载源代码:https://github.com/netty/netty.git 我下载的版本为4.1 2. eclipse导入maven工程. netty提 ...
- 深入netty源码解析之一数据结构
Netty是一个异步事件驱动的网络应用框架,它适用于高性能协议的服务端和客户端的快速开发和维护.其架构如下所示: 其核心分为三部分, 最低层为支持零拷贝功能的自定义Byte buffer: 中间层为通 ...
- 教你用 Netty 实现一个简单的 RPC!
众所周知,dubbo 底层使用了 Netty 作为网络通讯框架,而 Netty 的高性能我们之前也分析过源码,对他也算还是比较了解了. 今天我们就自己用 Netty 实现一个简单的 RPC 框架. 1 ...
- Netty 系列三(ByteBuf).
一.概述和原理 网络数据传输的基本单位总是字节,Netty 提供了 ByteBuf 作为它的字节容器,既解决了 JDK API 的局限性,又为网络应用程序提供了更好的 API,ByteBuf 的优点: ...
最新文章
- 创新工场论文入选NeurIPS 2019,研发最强“AI蒙汗药”
- 通过Redis实现分布式锁
- [总结]vue开发常见知识点及问题资料整理(持续更新)
- 01_Weblogic课程之概念篇:代理服务器,web服务器,应用程序服务器,JNDI概念,JTA概念,Java消息服务,Java验证和授权(JAAS),Java管理扩展,Web客户机,客户机应用程序
- SQLite 数据类型(http://www.w3cschool.cc/sqlite/sqlite-data-types.html)
- Scrapy匹配xpath时tbody标签的问题
- leetcode209. 长度最小的子数组(滑动窗口)
- [js] flash如何与js交互?
- python_魔法方法(二):算术运算
- Python面试题解答——第一部分
- 年轻人,被领导骂是怎样一种感觉?
- 苏锡常CIO俱乐部春季论坛暨2020年会(苏州站)圆满落幕!
- Map获取key的数组
- 第七章:项目成本管理 - (7.3 制定预算)
- CNN with Attention---channal and spatial attention(转)
- 机器学习之聚类算法——聚类效果评估可视化
- win7计算机自动关机设置在哪里设置方法,Win7小技巧:自动关机怎么设置?
- ubuntu 16.04.4 desktop版安装
- JS内置对象和数组方法
- R语言——多元线性回归
热门文章
- How to install plugin for Eclipse from .zip
- stomp 连接错误: Whoops! Lost connection to http://localhost:8080/spring13/stomp 的解决方法
- jvm(2)-java内存区域
- AQS的细节--自用,非正常教程
- Post请求如何取消异步
- java中的可检查和不检查_检查Java测试中发生了什么
- brew卸载jenv_使用brew,cask和jenv在MacOSX上设置多个Java JRE / JDK
- jgroups_JGroups:无需额外基础架构的领导人选举
- spring aop不执行_使用Spring AOP重试方法执行
- javaone_JavaOne 2015 –第二十版十大收获