长轮询 VS 长连接
客户端和服务端通信一般采用的是 http 请求, http 请求的缺点是只能由客户端发起, 服务端响应, 并且响应一旦完成请求就会被关闭. 当客户端需要即时性获取服务端消息的时候, 可以采用以下几种方式:
轮询: 客户端定时向服务器发送 Ajax 请求, 服务器接到请求后马上返回响应信息并关闭连接.
优点: 后端程序编写比较容易.
缺点: 请求中有大半是无用, 浪费带宽和服务器资源.(而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息, 这就增加了每次传输的数据量)
实例: 适于小型应用.
长轮询: 客户端向服务器发送 Ajax 请求, 服务器接到请求后 hold 住连接, 直到有新消息才返回响应信息并关闭连接 (或到了设定的超时时间关闭连接), 客户端处理完响应信息后再向服务器发送新的请求.
优点: 在无消息的情况下不会频繁的请求, 节省了网络流量, 解决了服务端一直疲于接受请求的窘境
缺点: 服务器 hold 连接会消耗资源, 需要同时维护多个线程, 服务器所能承载的 TCP 连接数是有上限的, 这种轮询很容易把连接数顶满.
实例: webQQ,Hi 网页版, Facebook IM.
长连接: 在页面里嵌入一个隐蔵 iframe, 将这个隐蔵 iframe 的 src 属性设为对一个长连接的请求, 服务器端就能源源不断地往客户端输入数据.
优点: 消息即时到达, 不发无用请求.
缺点: 服务器维护一个长连接会增加开销. iframe 正在逐步被废弃.
实例: Gmail 聊天
Flash Socket: 在页面中内嵌入一个使用了 Socket 类的 Flash 程序 JavaScript 通过调用此 Flash 程序提供的 Socket 接口与服务器端的 Socket 接口进行通信, JavaScript 在收到服务器端传送的信息后控制页面的显示.
优点: 实现真正的即时通信, 而不是伪即时.
缺点: 客户端必须安装 Flash 插件; 非 HTTP 协议, 无法自动穿越防火墙.
实例: 网络互动游戏.
WebSocket:
WebSocket 协议本质上是一个基于 TCP 的协议. 为了建立一个 WebSocket 连接, 客户端浏览器首先要向服务器发起一个 HTTP 请求, 这个请求和通常的 HTTP 请求不同, 包含了一些附加头信息, 其中附加头信息 "Upgrade: WebSocket" 表 明这是一个申请协议升级的 HTTP 请求, 服务器端解析这些附加的头信息然后产生应答信息返回给客户端, 客户端和服务器端的 WebSocket 连接就建立起来了, 双方就可以通过这个连接通道自由的传递信息, 并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接.
webSocket
WebSocket 是 html5 新增加的一种通信协议, 目前流行的浏览器都支持这个协议, 例如 Chrome,Safrie,Firefox,Opera,IE 等等.
代码示例
客户端
服务端
关于 webSocket 的详细使用方法可以参考阮一峰老师的 webSocket 教程
websocket 与 TCP,HTTP 的关系
为了建立一个 WebSocket 连接, 浏览器首先要向服务器发起一个 HTTP 请求, 这个请求和通常的 HTTP 请求不同, 包含了一些附加头信息, 其中附加头信息 Upgrade: WebSocket 表明这是一个申请协议升级的 HTTP 请求. 服务端解析这些头信息, 然后产生应答信息返回给客户端, 客户端和服务端的 WebSocket 连接就建立起来了. 双方就可以通过这个连接通道自由的传递信息, 并且这个连接会持续直到客户端或者服务端的某一方主动关闭连接.
WebSocket 与 http 协议一样都是基于 TCP 的, 所以他们都是可靠的协议, Web 开发者调用的 WebSocket 的 send 函数在 browser 的实现中最终都是通过 TCP 的系统接口进行传输的. WebSocket 和 Http 协议一样都属于应用层的协议, 那么他们之间有没有什么关系呢? 答案是肯定的, WebSocket 在建立握手连接时, 数据是通过 http 协议传输的. 但是在建立连接之后, 真正的数据传输阶段是不需要 http 协议参与的.
socket.io
node.JS 提供了高效的服务端运行环境, 但是由于浏览器端对 HTML5 的支持不一, 为了兼容所有浏览器, 提供卓越的实时的用户体验, 并且为程序员提供客户端与服务端一致的编程体验, 于是 socket.io 诞生. Socket.io 将 Websocket 和轮询 (Polling) 机制以及其它的实时通信方式封装成了通用的接口, 并且在服务端实现了这些实时机制的相应代码. 也就是说, Websocket 仅仅是 Socket.io 实现实时通信的一个子集.
socket.io 官网 https://github.com/socketio/socket.io
socket.io 实现了 polling 的以下通信机制
Adobe Flash Socket
大部分 PC 浏览器都支持的 Socket 模式, 不过是通过第三方嵌入到浏览器, 不在 W3C 规范内, 可能将逐步被淘汰. 况且, 大部分手机浏览器并不支持此种模式.
Ajax Long Polling
定时向服务端发送请求, 缺点是给服务端带来压力并出现信息更新不及时的现象.
Ajax multipart streaming
在 XMLHttpRequest 对象上使用某些浏览器支持的 multi-part 标志, Ajax 请求被发送给服务端并保持打开状态 (挂起状态), 每次需要向客户端发送信息, 就寻找一个挂起的 HTTP 请求响应给客户端, 并且所有的响应都会通过统一连接来写入.
Forever Iframem
永存的 Iframe 设计了一个置于页面中隐藏的 iframe 标签, 该标签的 src 属性指向返回服务端时间的 Servlet 路径. 每次在事件到达时, Servlet 写入并刷新一个新的 Script 标签, 该标签内部带有 JS 代码, iframe 的内容被附加上 script 标签, 标签中的内容就会得到执行. 这种方式的缺点是接收数据都是由浏览器通过 HTML 标签来处理的, 因此无法知道连接何时在哪一端被断开, 而且 iframe 标签在浏览器中将被逐步取消.
JSONP Polling
JSONP 轮询基本与 HTTP 轮询一样, 不同之处则是 JSONP 可发出跨域请求.
参考文献:
轮询, 长轮询, 长连接, socket 连接, WebSocket http://www.cnblogs.com/guanghe/p/9217015.html
webSocket 与 socket.io 介绍 https://www.cnblogs.com/mazg/p/5467960.html
来源: http://www.qdfuns.com/article/42837/f38b775a42daf4387d87502555464103.html