使用一個文本編輯器,把下面代碼複制儲存在一個 websocket.html 檔案中,然後隻要在浏覽器中打開它,頁面就會使用 websocket 自動連接配接,發送一個消息,顯示接受到的伺服器響應,然後關閉連接配接。
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript"type="text/javascript">
var wsUri ="ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
websocket.onmessage = function(evt) {
onMessage(evt)
websocket.onerror = function(evt) {
onError(evt)
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
function onClose(evt) {
writeToScreen("DISCONNECTED");
function onMessage(evt) {
writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>');
websocket.close();
function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data);
function doSend(message) {
writeToScreen("SENT: " + message);
websocket.send(message);
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
</html>
申請一個WebSocket對象,參數是需要連接配接的伺服器端的位址,同http協定使用http://開頭一樣,WebSocket協定的URL使用ws://開頭,另外安全的WebSocket協定使用wss://開頭。。
var wsUri ="ws://echo.websocket.org/";
websocket = new WebSocket(wsUri);
WebSocket對象一共支援四個消息 onopen, onmessage, onclose和onerror,
我們可以看出所有的操作都是采用消息的方式觸發的,這樣就不會阻塞UI,使得UI有更快的響應時間,得到更好的使用者體驗。
當Browser和WebSocketServer連接配接成功後,會觸發onopen消息;
如果連接配接失敗,發送、接收資料失敗或者處理資料出現錯誤,browser會觸發onerror消息;
當Browser接收到WebSocketServer發送過來的資料時,就會觸發onmessage消息,參數evt中包含server傳輸過來的資料;
當Browser接收到WebSocketServer端發送的關閉連接配接請求時,就會觸發onclose消息。
WebSocket與http協定一樣都是基于TCP的,是以他們都是可靠的協定,Web開發者調用的WebSocket的send函數在browser的實作中最終都是通過TCP的系統接口進行傳輸的。
WebSocket和Http協定一樣都屬于應用層的協定,那麼他們之間有沒有什麼關系呢?答案是肯定的,WebSocket在建立握手連接配接時,資料是通過http協定傳輸的,但是在建立連接配接之後,真正的資料傳輸階段是不需要http協定參與的。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1UDN4UmZyMDZ0UzYwUTMhhTNzQzMkdjMhFWY5cDNwQTLxMTNzAjMzEzLcRDMzEDMy8CX2kjMwITMvw1ZvxmYvwVbvNmLn9GbiRXauNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.png)
從下圖可以明顯的看到,分三個階段:
打開握手
資料傳遞
關閉握手
顯示了WebSocket主要的三步 浏覽器和 伺服器端分别做了那些事情。
WebSocket的優點
a)、伺服器與用戶端之間交換的标頭資訊很小,大概隻有2位元組;
b)、用戶端與伺服器都可以主動傳送資料給對方;
c)、不用頻率建立TCP請求及銷毀請求,減少網絡帶寬資源的占用,同時也節省伺服器資源;
當Web應用程式調用new WebSocket(url)接口時,Browser就開始了與位址為url的WebServer建立握手連接配接的過程。
1. Browser與WebSocket伺服器通過TCP三向交握建立連接配接,如果這個建立連接配接失敗,那麼後面的過程就不會執行,Web應用程式将收到錯誤消息通知。
2. 在TCP建立連接配接成功後,Browser/UA通過http協定傳送WebSocket支援的版本号,協定的字版本号,原始位址,主機位址等等一些列字段給伺服器端。
3. WebSocket伺服器收到Browser/UA發送來的握手請求後,如果資料包資料和格式正确,用戶端和伺服器端的協定版本号比對等等,就接受本次握手連接配接,并給出相應的資料回複,同樣回複的資料包也是采用http協定傳輸。
4. Browser收到伺服器回複的資料包後,如果資料包内容、格式都沒有問題的話,就表示本次連接配接成功,觸發onopen消息,此時Web開發者就可以在此時通過send接口想伺服器發送資料。否則,握手連接配接失敗,Web應用程式會收到onerror消息,并且能知道連接配接失敗的原因。
這個握手很像HTTP,但是實際上卻不是,它允許伺服器以HTTP的方式解釋一部分handshake的請求,然後切換為websocket
WebScoket協定中,資料以幀序列的形式傳輸。
考慮到資料安全性,用戶端向伺服器傳輸的資料幀必須進行掩碼處理。伺服器若接收到未經過掩碼處理的資料幀,則必須主動關閉連接配接。
伺服器向用戶端傳輸的資料幀一定不能進行掩碼處理。用戶端若接收到經過掩碼處理的資料幀,則必須主動關閉連接配接。
針對上情況,發現錯誤的一方可向對方發送close幀(狀态碼是1002,表示協定錯誤),以關閉連接配接。
使用Wireshark監控到的上面WebSocket例子的資料。
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: echo.websocket.org
Origin: null
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: Qcgtb1RJ6HceeTRLPFux/A==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
Cookie: __utma=9925811.951031439.1365242028.1365980711.1366068689.5; __utmc=9925811; __utmz=9925811.1365242028.1.1.utmcsr=websocket.org|utmccn=(referral)|utmcmd=referral|utmcct=/
HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Sec-WebSocket-Accept: 84Qpane33QhxOmcz8bGkFdE1AHk=
Server: Kaazing Gateway
Date: Tue, 16 Apr 2013 09:51:25 GMT
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
..a[
J6>h..8a/.{x%.0y..WebSocket rocks..i.....