为什么会有WebSocket协议呢?
因为HTTP有一个缺陷:通信只能由客户端发起。HTTP 协议做不到服务器主动向客户端推送信息。WebSocket协议是双向的,服务器端可以主动向客户端推送信息,客户端也可以主动向服务器发送消息,是真正的双向对话平等,属于服务器推送技术的一种。WebSocket建立在TCP协议上。
HTTP协议是这样通信的:客户端发起请求request,服务器端响应response,一个request对应一个response,而且这个response是被动的,不会主动向客户端发起。所以说,HTTP协议是被动性的,只能由客户端发起,不能主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器端有连续的状态变化,客户端要获知就比较麻烦,需要使用Ajax轮询(让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。这种方式效率低,非常浪费资源,因为需要不停连接,或者HTTP连接始终打开,既浪费了网络带宽,又浪费了CPU的利用率)或long poll(原理跟Ajax轮询差不多,它采取的是阻塞模式,也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。)每隔一段时间就发出一个询问,了解服务器是否有新的消息。因此,ajax轮询 需要服务器有很快的处理速度和资源,long poll 需要有很高的并发。
WebSocket
WebSocket只需要一次HTTP请求,让客户端发起请求,跟服务器端协商好建立WebSocket协议后就可以通信了,服务器端有新的消息就可以主动告知客户端。WebSocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求。相比之下,传统的方式要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输 identity info (鉴别信息),来告诉服务端你是谁。
socket.io
node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是socket.io诞生。在不支持websoket的浏览器中,socket.io可以降级为其他的通信方式,比如有AJAX long polling ,JSONP Polling等。
socket.io由JavaScript实现、基于Node.js、支持WebSocket协议用于实时通信、跨平台的开源框架,它包括了客户端的JavaScript和服务器端的Node.js。也就是说Socket.io将Websocket和轮询(Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时通信机制。Socket.io中主要使用了websocket,将轮询作为其辅助选项,提供的是相同的接口。其与node.js一样,也是事件驱动的。