websocket
websocket是web傳遞消息的一種協(xié)議。web傳遞消息的方式主要有輪詢(polling)、長輪詢(long-polling)、流(streaming)、插件提供socket、websocket幾種方式。
websocket是html5的協(xié)議,握手協(xié)議跟http一樣,握手完成之后建立TCP鏈接。
websocket建立的鏈接是持久,http的鏈接是非持久的。
http的生命周期通過Request來界定,也就是一個Request一個Response,在HTTP1.0中,這次HTTP請求就結束了。
在HTTP1.1中進行了改進,使得有一個keep-alive,也就是說,在一個HTTP連接中,可以發(fā)送多個Request,接收多個Response。但Response是被動的,不能主動發(fā)起。
使用websocket需要服務端、客戶端、代理同時支持。
socket.io
socket.io實現(xiàn)了polling和websocket兩種協(xié)議。如何使用,github上有example:
-
服務端
var server = require('http').createServer(); var io = require('socket.io')(server); io.on('connection', function(socket){ socket.on('event', function(data){}); socket.on('disconnect', function(){}); }); server.listen(3000); -
前端頁面需要引入socket.io.js,它是socketio生成的動態(tài)js
<script src="/socket.io/socket.io.js"></script> -
前端js
var socket = io(); socket.on('new message', function (data) { addChatMessage(data); });
運行example,監(jiān)聽網(wǎng)絡,可以看到發(fā)了4個?EIO***的請求(不知道為什么會發(fā)4次,第一個請求是客戶端告訴服務端我支持websocket)。polling和websocket方式都有:

polling和websocket最大的區(qū)別就是請求頭不一樣,websocket的請求頭如下所示:

把前端js代碼調整下,設置socket.io的options,讓它只連接websocket:
var socket = io({transports: ["websocket"]})
設置之后,只有一個websocket的?EIO***連接。連接完成之后第一次發(fā)送的數(shù)據(jù)設置多久執(zhí)行一次心跳(ping-pong)。之后每隔一定時間data中都會多出兩條數(shù)據(jù)。

參考資料
socket.io源碼
HTTP的長連接和短連接——Node上的測試
借助Nodejs探究WebSocket
Web 消息推送及 WebSocket 簡介
WebSocket 是什么原理?為什么可以實現(xiàn)持久連接?