摘要:一、為什么需要 WebSocket?初次接觸 WebSocket 的人,都會問同樣的問題:我們已經(jīng)有了 HTTP 協(xié)議,為什么還需要另一個協(xié)議?它能帶來什么好處?答案很簡單,因為 HTTP 協(xié)議有一個...
一、為什么需要 WebSocket?
初次接觸 WebSocket 的人,都會問同樣的問題:我們已經(jīng)有了 HTTP 協(xié)議,為什么還需要另一個協(xié)議?它能帶來什么好處?
答案很簡單,因為 HTTP 協(xié)議有一個缺陷:通信只能由客戶端發(fā)起。
舉例來說,我們想了解今天的天氣,只能是客戶端向服務(wù)器發(fā)出請求,服務(wù)器返回查詢結(jié)果。HTTP 協(xié)議做不到服務(wù)器主動向客戶端推送信息。
這種單向請求的特點,注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶端要獲知就非常麻煩。我們只能使用"輪詢":每隔一段時候,就發(fā)出一個詢問,了解服務(wù)器有沒有新的信息。最典型的場景就是聊天室。
輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)。因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發(fā)明的。
二、簡介
WebSocket 協(xié)議在2008年誕生,2011年成為國際標準。所有瀏覽器都已經(jīng)支持了。
它的最大特點就是,服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種。
其他特點包括:
(1)建立在 TCP 協(xié)議之上,服務(wù)器端的實現(xiàn)比較容易。
(2)與 HTTP 協(xié)議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。
(3)數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。
(4)可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)。
(5)沒有同源限制,客戶端可以與任意服務(wù)器通信。
(6)協(xié)議標識符是ws(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL。
WebSocket 屬性:
Socket.readyState
只讀屬性 readyState 表示連接狀態(tài),可以是以下值:
0 --- 表示連接尚未建立。
1 --- 表示連接已建立,可以進行通信。
2 --- 表示連接正在進行關(guān)閉。
3 --- 表示連接已經(jīng)關(guān)閉或者連接不能打開。
WebSocket 事件:
事件事件處理程序描述
openSocket.onopen---連接建立時觸發(fā)
messageSocket.onmessage---客戶端接收服務(wù)端數(shù)據(jù)時觸發(fā)
errorSocket.onerror---通信發(fā)生錯誤時觸發(fā)
closeSocket.onclose---連接關(guān)閉時觸發(fā)
WebSocket 方法:
Socket.send()---使用連接發(fā)送數(shù)據(jù)
Socket.close()---關(guān)閉連接
三、客戶端的簡單示例
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>WebSocket簡單實例</title> <script type="text/javascript"> function WebSocketTest() { if ("WebSocket" in window) { alert("您的瀏覽器支持 WebSocket!"); // 打開一個 web socket var ws = new WebSocket("ws://localhost:8080/test"); ws.onopen = function() { // Web Socket 已連接上,使用 send() 方法發(fā)送數(shù)據(jù) ws.send("發(fā)送數(shù)據(jù)"); alert("數(shù)據(jù)發(fā)送中..."); }; ws.onmessage = function (evt) { var received_msg = evt.data; alert("數(shù)據(jù)已接收..."); }; ws.onclose = function() { // 關(guān)閉 websocket alert("連接已關(guān)閉..."); }; } else { // 瀏覽器不支持 WebSocket alert("您的瀏覽器不支持 WebSocket!"); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">運行 WebSocket</a> </div> </body> </html>