一、HTTP协议的弊端
将HTTP协议的主要弊端总结如下:
(1)半双工协议:可以在客户端和服务端2个方向上传输,但是不能同时传输。同一时刻,只能在一个方向上传输。
(2) HTTP消息冗长:相比于其他二进制协议,有点繁琐。
(3) 针对服务器推送的黑客攻击,例如长时间轮询。
现在很多网站的消息推送都是使用轮询,即客户端每隔1S或者其他时间给服务器发送请求,然后服务器返回最新的数据给客户端。HTTP协议中的Header非常冗长,因此会占用很多的带宽和服务器资源。
比较新的技术是Comet,使用了AJAX轮询。虽然可以双向通信,但是依然需要发送请求,而且在Comet中,普遍采用了长连接,也会大量消耗服务器的带宽和资源。
但是为了解决这个问题,HTML5定义的WebSocket协议。
WebSocket基于TCP双向全双工协议,即在同一时刻,即可以发送消息,也可以接收消息,相比于HTTP协议,是一个性能上的提升。
特点:
单一的TCP连接,全双工;
对代理、防火墙和路由器透明;
无安全开销;
通过”ping/pong”帧保持链路激活;
服务器可以主动传递消息给客户端,不再需要客户端轮询;
无头部信息、Cookie和身份验证;
拥有以上特点的WebSocket就是为了取代轮询和Comet技术,使得客户端浏览器具备像C/S架构下桌面系统一样的实时能力。
浏览器通过js建立一个WebSocket的请求,连接建立后,客户端和服务器端可以通过TCP直接交换数据。
因为WebSocket本质上是一个TCP连接,稳定,所以在Comet和轮询比拥有性能优势。
client端发送握手请求,这个请求和普通的HTTP请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: Websocket”表明这是一个申请协议升级的HTTP请求。服务器尝试解析这个信息,然后返回应答信息给客户端,因此客户端和服务器端的WebSocket连接就建立起来了,双方可以通过这个连接通道自由的传递信息。这个连接会持续到某一方主动断开连接。
client消息中的”Sec-WebSocket-Key”是随机的,服务器端会用这些数据来构造一个”SHA-1”的信息摘要,把”Sec-WebSocket-Key”加上一个魔幻字符串。使用”SHA-1”加密,然后进行BASE64编码,将结果作为”Sec-Webscoket-Accept”头的值。
握手成功,连接建立后,以”Messages”的方式通信。一个消息由一个或者多个”帧”组成。帧都有自己的类型,同一消息的多个帧类型相同。广义上,类型可以是文本、二进制、控制帧如信号。
安全方法是关闭底层TCP连接以及TLS会话。底层的TCP连接,正常情况下,应该由服务器先关闭。异常时(比如合理的时间内没有接收到服务器的TCP Close),可以由客户端发起TCP Close。因此,在client发起TCP Close时,服务器应该立即发起一个TCP Close操作;客户端则等待服务器的TCP Close;关闭消息带有一个状态码和可选的关闭原因,它必须按照协议要求发送一个Close控制帧。
官方demo:
http://netty.io/4.1/xref/io/netty/example/http/websocketx/server/package-summary.html
上边文章原文:https://blog.csdn.net/qq_32447301/article/details/80788054
作用都一样都是处理输入输出的类,可以文件IO也可以网络IO
是流的概念,基于字节流字符流进行操作,读写一般需要byte数组做缓冲区,其stream是单向的,inputstream只能读,outstream只能写,
是基于channel(通道)和buffer(缓冲区)的操作,提供了非阻塞式的高伸缩网络,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通 道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道,NIO中的通道是双向的,读写操作都可以进行
常用的 Channel 类有:FileChannel、 DatagramChannel、ServerSocketChannel(服务端) 和 SocketChannel(客户端)。FileChannel 用于文件的数据读写, DatagramChannel 用于 UDP 的数据读写,ServerSocketChannel 和 SocketChannel 用于 TCP 的 数据读写。
nio中的网络通道是非阻塞Io实现是基于事件驱动的,适用于那些即时通信的服务,相比java socket服务,一个客户端一个连接,或者线程连接池的开销,new io使用非阻塞方式处理,可以一个线程处理大量客户端连接请求
nio种定义了一些网络事件,比如读写事件连接事件等,selector选择器会不停的检测所有的客户端连接,有事件发生才会针对每个事件响应处理,这样一个单线程管理多个通道连接,不必为每个连接建立线程,避免多线程的上下文切换开销
是一个基于 NIO 的网络编程框架,使用 Netty 可以帮助你快速、简单的开发出一 个网络应用,相当于简化和流程化了 NIO 的开发过程。 作为当前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、 通信行业等获得了广泛的应用,知名的 Elasticsearch 、Dubbo nacos框架内部都采用了 Netty。
服务器端用一个线程通过多路复用,selector监控所有客户端的事件(读写连接等事件),但是如果客户端连接数量较多,将无法支撑,咱们前面的 NIO 案例种模型。
服务端采用一个线程专门处理客户端连接请求,在采用一个线程池负责IO操作,在绝大数场景下,改模型都能满足使用
在线程池模型上在做一个升级,抽象出两组线程池,一组BossGroup线程池负责接收客户端连接,一组workGroup线程池负责网络读写操作,NioEventLoop表示不断循环执行处理任务的线程,每个NioEventLoop都有一个selector,用于监听绑定在其上的socket网络通道,内部采用串行化设计,从消息读取->解码->处理->编码->发送,始终IO线程NioEventLoop负责
一个 NioEventLoopGroup 下包含多个 NioEventLoop
每个 NioEventLoop 中包含有一个 Selector,一个 taskQueue
每个 NioEventLoop 的 Selector 上可以注册监听多个 NioChannel
每个 NioChannel 只会绑定在唯一的 NioEventLoop 上
每个 NioChannel 都绑定有一个自己的 ChannelPipeline
netty异步模型
FUTURE, CALLBACK 和 HANDLER
Netty 的异步模型是建立在 future 和 callback 的之上的。callback 大家都比较熟悉了,这 里重点说说 Future,它的核心思想是:假设一个方法 fun,计算过程可能非常耗时,等待 fun 返回显然不合适。那么可以在调用 fun 的时候,立马返回一个 Future,后续可以通过 Future 去监控方法 fun 的处理过程。 在使用 Netty 进行编程时,拦截操作和转换出入站数据只需要您提供 callback 或利用 future 即可。这使得链式操作简单、高效, 并有利于编写可重用的、通用的代码。Netty 框 架的目标就是让你的业务逻辑从网络基础应用编码中分离出来、解脱出来