>>>點擊獲取更多文章<<<javascript
在談Websockt以前,先談談推送技術。php
它是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。html
比較新的技術去作輪詢,包括 長輪詢__,__iframe流 ,這種技術雖然能夠雙向通訊,但依然須要反覆發出請求。並且在Comet中,廣泛採用的長連接,也會消耗服務器資源。java
長輪詢是在打開一條鏈接之後保持,等待服務器推送來數據再關閉的方式。node
iframe流方式是在頁面中插入一個隱藏的iframe,利用其src屬性在服務器和客戶端之間建立一條長連接,服務器向iframe傳輸數據(一般是HTML,內有負責插入信息的javascript),來實時更新頁面。python
iframe流方式的優勢是瀏覽器兼容好,Google公司在一些產品中使用了iframe流,如Google Talk。nginx
在這種狀況下,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。git
Websocket使用ws或wss的統一資源標誌符,相似於HTTPS,其中wss表示在TLS之上的Websocket。如:github
ws://example.com/wsapi wss://secure.example.com/
Websocket使用和 HTTP 相同的 TCP 端口,能夠繞過大多數防火牆的限制。默認狀況下,Websocket協議使用80端口;運行在TLS之上時,默認使用443端口。web
ws://example.com:80/some/path //80端口 wss://example.com:443/some/path //443端口
WebSocket是一種在單個TCP鏈接上進行全雙工通訊的協議。
WebSocket 協議在2008年誕生,2011年成爲國際標準。全部瀏覽器都已經支持了。在WebSocket API中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。它的最大特色就是,服務器能夠主動向客戶端推送信息,客戶端也能夠主動向服務器發送信息,是真正的雙向平等對話,屬於服務器推送技術的一種。
WebSocket 是獨立的、建立在 TCP 上的協議。
Websocket 經過 HTTP/1.1 協議的101狀態碼進行握手。
爲了建立Websocket鏈接,須要經過瀏覽器發出請求,以後服務器進行迴應,這個過程一般稱爲「握手」(handshaking)。
一個典型的Websocket握手請求以下:
客戶端請求
GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: example.com Origin: http://example.com Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ== Sec-WebSocket-Version: 13
服務器迴應
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s= Sec-WebSocket-Location: ws://example.com/
Connection必須設置Upgrade,表示客戶端但願鏈接升級。
Upgrade字段必須設置Websocket,表示但願升級到Websocket協議。
Sec-WebSocket-Key是隨機的字符串,服務器端會用這些數據來構造出一個SHA-1的信息摘要。把「Sec-WebSocket-Key」加上一個特殊字符串「258EAFA5-E914-47DA-95CA-C5AB0DC85B11」,而後計算SHA-1摘要,以後進行BASE-64編碼,將結果作爲「Sec-WebSocket-Accept」頭的值,返回給客戶端。如此操做,能夠儘可能避免普通HTTP請求被誤認爲Websocket協議。
Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13,以前草案的版本均應當棄用。
下面是一個網頁腳本的例子,基本上一眼就能明白。
var ws = new WebSocket("wss://echo.websocket.org"); ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!"); }; ws.onmessage = function(evt) { console.log( "Received Message: " + evt.data); ws.close(); }; ws.onclose = function(evt) { console.log("Connection closed."); };
其中 WebSocket 對象做爲一個構造函數,用於新建 WebSocket 實例。實例對象的全部屬性和方法清單,參見這裏。
在服務器方面,網上都有不一樣對websocket支持的服務器:
php-http://code.google.com/p/phpw...
jetty-http://jetty.codehaus.org/jetty/(版本7開始支持websocket)[永久失效連接]
netty-http://www.jboss.org/netty
ruby-http://github.com/gimite/web-...
Kaazing-https://web.archive.org/web/2...://www.kaazing.org/confluence/display/KAAZING/Home
Tomcat-http://tomcat.apache.org/(7.0.27支持websocket,建議用tomcat8,7.0.27中的接口已通過時)
WebLogic-http://www.oracle.com/us/prod...(12.1.2開始支持)[永久失效連接]
node.js-https://github.com/Worlize/We...
node.js-http://socket.io
nginx-http://nginx.com/
mojolicious-http://mojolicio.us/
python-https://github.com/abourget/g...
Django-https://github.com/stephenmcd...
erlang-https://github.com/ninenines/...