一、它是什么?
WebSocket是HTML5開始提供的一種瀏覽器與服務器間進行全雙工通訊的網絡技術。依靠這種技術可以實現客戶端和服務器端的長連接,雙向實時通信。
1.1 特點
- 時間驅動
- 異步
- 使用ws或者wss協議的客戶端socket
- 能夠實現真正意義上的推送功能
1.2 限制
- 少部分瀏覽器不支持,瀏覽器支持的程度與方式有區別。
1.3 前置小知識(懂得大佬可以跳過,或者溫習一下也可)
- TCP/IP協議
TCP/IP協議是目前應用最為廣泛的協議,是構成Internet國際互聯網協議的最為基礎的協議,由TCP和IP協議組成:
TCP協議:面向連接的、可靠的、基於字節流的傳輸層通信協議,負責數據的可靠性傳輸的問題。
IP協議:用於報文交換網絡的一種面向數據的協議,主要負責給每台網絡設備一個網絡地址,保證數據傳輸到正確的目的地。
- UDP協議
UDP特點:無連接、不可靠、基於報文的傳輸層協議,優點是發送后不用管,速度比TCP快。
- B/S架構的系統多使用HTTP協議,HTTP協議的特點:
- 無狀態協議
- 用於通過 Internet 發送請求消息和響應消息
- 使用端口接收和發送消息,默認為80端口
- 底層通信還是使用Socket完成。
HTTP協議決定了服務器與客戶端之間的連接方式,無法直接實現消息推送(F5已壞),一些變相的解決辦法:
- 雙向通信與消息推送
輪詢
:客戶端定時向服務器發送Ajax請求,服務器接到請求后馬上返回響應信息並關閉連接。 優點:后端程序編寫比較容易。 缺點:請求中有大半是無用,浪費帶寬和服務器資源。 實例:適於小型應用。
長輪詢
:客戶端向服務器發送Ajax請求,服務器接到請求后hold住連接,直到有新消息才返回響應信息並關閉連接,客戶端處理完響應信息后再向服務器發送新的請求。 優點:在無消息的情況下不會頻繁的請求,耗費資小。 缺點:服務器hold連接會消耗資源,返回數據順序無保證,難於管理維護。 Comet異步的ashx,實例:WebQQ、Hi網頁版、Facebook IM。
長連接
:在頁面里嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設為對一個長連接的請求或是采用xhr請求,服務器端就能源源不斷地往客戶端輸入數據。 優點:消息即時到達,不發無用請求;管理起來也相對便。 缺點:服務器維護一個長連接會增加開銷。 實例:Gmail聊天
Flash Socket
:在頁面中內嵌入一個使用了Socket類的 Flash 程序JavaScript通過調用此Flash程序提供的Socket接口與服務器端的Socket接口進行通信,JavaScript在收到服務器端傳送的信息后控制頁面的顯示。 優點:實現真正的即時通信,而不是偽即時。 缺點:客戶端必須安裝Flash插件;非HTTP協議,無法自動穿越防火牆。 實例:網絡互動游戲。
二、為什么是它(應用場景)?
B/S結構的軟件項目中有時客戶端需要實時的獲得服務器消息,但默認HTTP協議只支持請求響應模式,這樣做可以簡化Web服務器,減少服務器的負擔,加快響應速度,因為服務器不需要與客戶端長時間建立一個通信鏈接,但不容易直接完成實時的消息推送功能,如聊天室、后台信息提示、實時更新數據等功能,但通過polling、Long polling、長連接、Flash Socket以及HTML5中定義的WebSocket
能完成該功能需要。
三、怎么使用它
3.1 websocket客戶端
websocket允許通過JavaScript建立與遠程服務器的連接,從而實現客戶端與服務器間雙向的通信。在websocket中有兩個方法:
- send() 向遠程服務器發送數據
- close() 關閉該websocket鏈接
- websocket同時還定義了幾個監聽函數
- onopen 當網絡連接建立時觸發該事件
- onerror 當網絡發生錯誤時觸發該事件
- onclose 當websocket被關閉時觸發該事件
- onmessage 當websocket接收到服務器發來的消息的時觸發的事件,也是通信中最重要的一個監聽事件。msg.data
- websocket還定義了一個readyState屬性,這個屬性可以返回websocket所處的狀態:
- CONNECTING(0) websocket正嘗試與服務器建立連接
- OPEN(1) websocket與服務器已經建立連接
- CLOSING(2) websocket正在關閉與服務器的連接
- CLOSED(3) websocket已經關閉了與服務器的連接
websocket的url開頭是ws,如果需要ssl加密可以使用wss,當我們調用websocket的構造方法構建一個websocket對象(new WebSocket(url))的之后,就可以進行即時通信了。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>WebSocket 客戶端</title>
</head>
<body>
<div>
<input type="button" id="btnConnection" value="連接" />
<input type="button" id="btnClose" value="關閉" />
<input type="button" id="btnSend" value="發送" />
</div>
<script src="js/jquery-1.11.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var socket;
if(typeof(WebSocket) == "undefined") {
alert("您的瀏覽器不支持WebSocket");
return;
}
$("#btnConnection").click(function() {
//實現化WebSocket對象,指定要連接的服務器地址與端口
socket = new WebSocket("ws://192.168.1.2:8888");
//打開事件
socket.onopen = function() {
alert("Socket 已打開");
//socket.send("這是來自客戶端的消息" + location.href + new Date());
};
//獲得消息事件
socket.onmessage = function(msg) {
alert(msg.data);
};
//關閉事件
socket.onclose = function() {
alert("Socket已關閉");
};
//發生了錯誤事件
socket.onerror = function() {
alert("發生了錯誤");
}
});
//發送消息
$("#btnSend").click(function() {
socket.send("這是來自客戶端的消息" + location.href + new Date());
});
//關閉
$("#btnClose").click(function() {
socket.close();
});
</script>
</body>
</html>