webSocket将网络套接字引入到了客户端和服务端,众所周知,我们之前实现聊天功能,可能需要古老的Socket技术,亦或者是古老的DWR框架,反向Ajax技术,再有可能就是Comet服务器推技术,H5的webSocket很轻松的可以进行聊天功能实现,Netty和H5的WebSocket结合非常的简单,Netty为我们封装了其协议类,我们可以很方便的进行使用。
ws特点:
单一的tcp连接,双方可通信。
对代理、防火墙和路由器透明。
无头部信息、Cookie和身份验证。
无安全开销。
通过ping/pong帧保持链路激活。
服务器可主动传递消息给客户端,不再需要客户端轮询。
Netty实现文件服务器(基于HTTP协议)
HTTP(超文本传输协议)是建立在TCP传输协议之上的应用层协议,他目前主流是针对于WEB开发,HTTP协议应用非常广泛,因此掌握HTTP协议的开发非常之重要。我们主要讲解Netty如何基于HTTP协议进行开发,那么使用Netty的Http协议也是异步非阻塞的。
Http协议特点:
简单:客户端请求服务器时们只需要指定URL和携带必要的参数即可
灵活:Http协议允许传输任意类型的数据对象,传输内容由HTTP消息头中的Content-Type加以标记。
无状态:Http协议是无状态的,无状态指的是协议对事务处理没有记忆能力。这意味着如果后续处理需要之前的信息,则它必须重新获取。也从侧面体现Http的设计是为了使网络传输更加的轻量级、敏捷,负载较轻。
Http协议组成部分:
请求行
请求头
请求正文(实体内容)
Http协议请求方式:
GET获取Request-URI所标识的资源
POST:在Request-URI所标识的资源附加新的提交数据
HEAD:请求获取由Request-URI所标识的资源的响应消息头
PUT:请求服务器存储一个资源,并用Request-URI作为标识
DELETE:请求服务器删除Request-URI所标识的资源
TRACE:请求服务器回送收到的请求信息,主要是测试和诊断使用(@trace)
CONNECT:保留将来使用
OPTIONS:请求查询服务器的性能忙活着查询相关资源的选项和需求.
Http协议的响应消息:响应消息也是由三部分组成的:状态行、消息头。响应正文
响应状态种类:
1xx:提示信息。表示请求已经接收继续处理。
2xx:成功。表示请求已经接收成功。
3xx:重定向。要尧成的请求必须进行更进一步的操作。
4xx:客户端错误。可能是请求语法错误或者请求无法实现
5xx:服务器端错误。服务器未能处理请求(可能内部出现异常)。
常见相应状态码:
200 OK成功。
400 Bad Reuqest错误的请求语法,不能被服务器理解。
401 Unauthorized:请求未经授权。
403 Forbidden:服务器收到请求,但请求被服务器拒绝。
404 Not Found:请求资源不存在
405 Method Not Allowed:请求方式不被允许,如只支持get请求,但客户端使用了post
请求)
500 Inernal server Error:服务器发送不可预期的错误。
503 server Unavailable:服务器当前不能处理客户端请求,一段时间后可能恢复正常
Netty的Http协议栈无论从性能上还是可靠性上都表现优异,非常适合WEB容器的场景下引用,相比于传统的Tomcat、Jetty等Web容器,它更加的轻量和小巧,灵活性和制定性也更好。
我们来看一个简单的Http服务器开发实例。
然后我们看一个Http文件服务端下载实例,和上传实例。
Netty 在使用的时候在管道里面添加一些固定的配置
Netty文件文件上传下载(netty无法保证可靠性)
Netty文件下载
Chunked方法 文件传输
文件很大分块上传下载本质是多次http请求
Netty文件上传
断点续传核心添加标记httpRange
Netty相对spring springMVC上传文件的优势,netty是非阻塞异步的传输速度相对较快。
大文件上传框架:
Fastdfs(支持小文件传输) 和 hdfs(不支持小文件传输,可以支持断点续传)
8 最佳实践(数据通信、心跳检测)
我们需要了解下在真正项目应用中如何去考虑Netty的使用,大体上对于一些参数设置都是根据服务器性能决定的。这个不是最主要的。
我们需要考虑的问题是两台机器(甚至多台)使用Netty的怎样进行通信,我个人大体上把他分为三种:
1第一种,使用长连接通道不断开的形式进行通信,也就是服务器和客户端的通道一直处于开启状态,如果服务器性能足够好,并且我们的客户端数量也比较少的情况下,我还是推荐这种方式的。
2第二种,一次性批量提交数据,采用短连接方式。也就是我们会把数据保存在本地临时缓冲区或者临时表里,当达到临界值时进行一次性批量提交,又或者根据定时任务轮询提交,这种情况弊端是做不到实时性传输,在对实时性不高的应用程序中可以推荐使用。
3第三种,我们可以使用一种特殊的长连接,在指定某一时间之内,服务器与某台客户端没有任何通信,则断开连接。下次连接则是客户端向服务器发送请求的时候,再次建立连接。但是这种模式我们需要考虑2个因素:
1如何在超时(即服务器和客户端没有任何通信)后关闭通道?关闭通道后我们又如何再次建立连接?
通过线程重新进行连接。
2客户端宕机时,我们无需考虑,下次客户端重启之后我们就可以与服务器建立连接,但是服务器宕机时,我们的客户端如何与服务器进行连接呢?
客户端宕机不需要考虑