成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

初探WebSocket

Channe / 1258人閱讀

摘要:流控制通常就是在客戶端的頁面使用一個隱藏的窗口向服務(wù)端發(fā)出一個長連接的請求。和長鏈接以上幾種服務(wù)器推的技術(shù)中長輪詢和流控制其實都是基于長鏈接來實現(xiàn)的,也就是中所謂的。通信協(xié)議于年被定為標準,并被所補充規(guī)范。

初探WebSocket

node websocket socket.io

我們平常開發(fā)的大部分web頁面都是主動‘拉’的形式,如果需要更新頁面內(nèi)容,則需要“刷新”一個,但Slack工具卻能主動收到信息,好像服務(wù)端能主動給客戶端推送信息,請研究一下這是怎么實現(xiàn)的。

WebSocket

websocket是HTML5中新引進的一種 協(xié)議 ,它是一種協(xié)議就像(HTTP,FTP在tcp/ip協(xié)議棧中屬于應(yīng)用層)而不是簡單的一個函數(shù)。它本身及基于TCP協(xié)議的一種新的協(xié)議。

WebSocket的產(chǎn)生

websocket是基于web的實時性而產(chǎn)生的,說到這里就不得不要追溯一下web的歷史了,在2005年(也就是ajax還沒誕生)以前,我們?nèi)绻胍谝粋€頁面顯示顯示不同的內(nèi)容,或者說頁面內(nèi)跳轉(zhuǎn),只能是通過點擊然后路由跳轉(zhuǎn),在ajax誕生之后,網(wǎng)頁開始變得動態(tài)了。但是所有的HTTP通信還都是由客戶端控制的,這就要需要長連接,定期輪詢或者長輪詢,來和服務(wù)器溝通來更新數(shù)據(jù)。

WebSocket之前的服務(wù)器“推”的技術(shù)

定期輪詢(ajax輪詢):瀏覽器在特定的時間給服務(wù)器發(fā)送請求,查看服務(wù)器是否有信息數(shù)據(jù)。

優(yōu)點:后端程序編寫比較容易。
缺點:請求中有大半是無用,浪費帶寬和服務(wù)器資源。
實例:適于小型應(yīng)用。

長輪詢:其實和上面的原理差不多,是對ajax輪詢進行了改進和提高??蛻舳撕头?wù)端建立連接之后,一直保持通信(阻塞模式),如果服務(wù)器沒有新消息就一直保持通信,直到服務(wù)器有新的消息,然后返回給客戶端,客戶端與服務(wù)器斷開連接,此時客戶端可以繼續(xù)和服務(wù)器進行連接。

優(yōu)點:在無消息的情況下不會頻繁的請求,耗費資源小。
缺點:服務(wù)器hold連接會消耗資源,返回數(shù)據(jù)順序無保證,難于管理維護。
實例:舊的 WebQQ、Hi網(wǎng)頁版、Facebook IM。

流控制:通常就是在客戶端的頁面使用一個隱藏的窗口向服務(wù)端發(fā)出一個長連接的請求。服務(wù)器端接到這個請求后作出回應(yīng)并不斷更新連接狀態(tài)以保證客戶端和服務(wù) 器端的連接不過期。通過這種機制可以將服務(wù)器端的信息源源不斷地推向客戶端。比如在頁面里嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設(shè)為對一個長連接的請求或是采用xhr請求,服務(wù)器端就能源源不斷地往客戶端輸入數(shù)據(jù)。

SSE,Comet,使用長鏈接進行通訊。

優(yōu)點:消息即時到達,不發(fā)無用請求;管理起來也相對方便。
缺點:服務(wù)器維護一個長連接會增加開銷。
實例:Gmail聊天

Flash Socket:在頁面中內(nèi)嵌入一個使用了Socket類的 Flash 程序JavaScript通過調(diào)用此Flash程序提供的Socket接口與服務(wù)器端的Socket接口進行通信,JavaScript在收到服務(wù)器端傳送的信息后控制頁面的顯示。

優(yōu)點:實現(xiàn)真正的即時通信,而不是偽即時。
缺點:客戶端必須安裝Flash插件;非HTTP協(xié)議,無法自動穿越防火墻。
實例:網(wǎng)絡(luò)互動游戲。

HTTP1.1和長鏈接

以上幾種服務(wù)器“推”的技術(shù)中:長輪詢和流控制其實都是基于長鏈接來實現(xiàn)的,也就是 http1.1 中所謂的 keep-alive。在一個TCP連接上可以傳送多個HTTP請求和響應(yīng),減少了建立和關(guān)閉連接的消耗和延遲。

HTTP是無狀態(tài)的,也就是說,瀏覽器和服務(wù)器每進行一次HTTP操作,就建立一次連接,但任務(wù)結(jié)束就中斷連接。如果客戶端瀏覽器訪問的某個HTML或其他類型的Web頁中包含有其他的Web資源,如JavaScript文件、圖像文件、CSS文件等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話

HTTP1.1和HTTP1.0相比較而言,最大的區(qū)別就是HTTP1.1默認支持持久連接(最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態(tài)的,或者說是不可以信任的。

在向客戶發(fā)送所請求文件的同時,服務(wù)器并沒有存儲關(guān)于該客戶的任何狀態(tài)信息。即便某個客戶在幾秒鐘內(nèi)再次請求同一個對象,服務(wù)器也不會響應(yīng)說:自己剛剛給它發(fā)送了這個對象。相反,服務(wù)器重新發(fā)送這個對象,因為它已經(jīng)徹底忘記早先做過什么。既然HTTP服務(wù)器不維護客戶的狀態(tài)信息,我們于是 說HTTP是一個無狀態(tài)的協(xié)議(stateless protocol)。

基于http協(xié)議的長連接減少了請求,減少了建立連接的時間,但是每次交互都是由客戶端發(fā)起的,客戶端發(fā)送消息,服務(wù)端才能返回客戶端消息。因為客戶端也不知道服務(wù)端什么時候會把結(jié)果準備好,所以客戶端的很多請求是多余的,僅是維持一個心跳,浪費了帶寬。

WebSocket WebSocket簡介

WebSocket 協(xié)議在2008年誕生,2011年成為國際標準。所有瀏覽器都已經(jīng)支持了。WebSocket通信協(xié)議于2011年被IETF定為標準RFC 6455,并被RFC7936所補充規(guī)范。

關(guān)于HTML5的故事很多人都是知道的,w3c放棄了HTML,然后有一群人(也有說是這些人供職的公司,不過官方的文檔上是說的個人)創(chuàng)立了WHATWG組織來推動HTML語言的繼續(xù)發(fā)展,同時,他們還發(fā)展了很多關(guān)于Web的技術(shù)標準,這些標準不斷地被官方所接受。WebSocket就屬于WHATWG發(fā)布的Web Application的一部分(即HTML5)的產(chǎn)物。

它的最大特點就是,服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種。

建立在 TCP 協(xié)議之上,服務(wù)器端的實現(xiàn)比較容易。

與 HTTP 協(xié)議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。

數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。

可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)。

沒有同源限制,客戶端可以與任意服務(wù)器通信。

協(xié)議標識符是ws(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL。

其中 Upgrade: websocket Connection: Upgrade 告訴服務(wù)器我們發(fā)起的是一個 WebSocket 請求。Sec-WebSocket-Key 是一個 Base64encode 的值,這個是瀏覽器隨機生成的,驗證服務(wù)器是不是真的是Websocket助理。
然后,Sec_WebSocket-Protocol 是一個用戶定義的字符串,用來區(qū)分同URL下,不同的服務(wù)所需要的協(xié)議。
最后,Sec-WebSocket-Version 是告訴服務(wù)器所使用的WebsocketDraft(協(xié)議版本)。

HTML5 Web Socket API
詳細接口文檔:MDN WebSocket

創(chuàng)建對象:
var ws = new WebSocket(url,name);
url為WebSocket服務(wù)器的地址,name為發(fā)起握手的協(xié)議名稱,為可選擇項。

發(fā)送文本消息:
ws.send(msg);
msg為文本消息,對于其他類型的可以通過二進制形式發(fā)送。

接收消息:
ws.onmessage = (function(){...})();

錯誤處理:
ws.onerror = (function(){...})();

關(guān)閉連接:
ws.close();

我們借助這個測試接口 wss://echo.websocket.org 來做一個小demo。

公用html(下面的代碼基本也是這個結(jié)構(gòu)):

客戶端簡單例子

這里我們走Kaazing WebSocket為我們提供的接口,這個接口將完整返回我們所發(fā)送的數(shù)據(jù)。

狀態(tài):

返回數(shù)據(jù):

JS:

var show = document.getElementById("state"),
    msg  = document.getElementById("msg"),
    st   = document.getElementById("sendText"),
    sb   = document.getElementById("sendBtn");

if ("WebSocket" in window) {
  var ws = new WebSocket("wss://echo.websocket.org");

  ws.onopen = function(e) { 
    show.innerText = "WebSocket連接成功~";
    ws.send("Hello WebSockets!");
  };

  ws.onmessage = function(e) {
    msg.innerText = e.data;
  };

  ws.onclose = function(e) {
      show.innerText = "WebSocket連接關(guān)閉~";
  }

  sb.addEventListener("click",function(){
      ws.send(st.value);
  })

}else{
  alert("你的瀏覽器不支持WebSocket");
}

nodejs-websocket

nodejs-websocket是一個nodeJs的模塊,我們可以用它來輕易地為我們之前的代碼多帶帶搭建一個WebSocket的nodeJs服務(wù)端。

yarn add nodejs-websocket
var ws = require("nodejs-websocket")

// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {
    console.log("New connection")
    conn.on("text", function (str) {
        console.log("Received "+str)
        conn.sendText(str.toUpperCase()+"!!!")
    })
    conn.on("close", function (code, reason) {
        console.log("Connection closed")
    })
}).listen(8001)
Socket.io

在某種程度上,socket.io就是websocket,其實socket.io與websocket不是一回事,而且websocket可以說是socket.io的一個子集,socket.io的底層實現(xiàn)其實有5種方式,websocket只是其中一種,只不過在默認的情況下,我們建立的socket.io連接,底層也是調(diào)用websocket的實例。當我們io.connect()建立一個socket連接的時候,返回的是namespace實例,namespace實例中有個socket實例,當新建一個連接,或者發(fā)送一條消息的時候,namespace->socket->transport->websocket(xhrpolling...),其實發(fā)送一條消息真正的發(fā)送者還是底層的websocket或是xhrpolling或其他的幾種,而socket.io只是一個組織者,當我們需要建立連接的時候,它自己會在其內(nèi)部挑選一種連接方式,然后實現(xiàn)連接。

Socket.io都實現(xiàn)了Polling中的那些通信機制呢?

Adobe? Flash? Socket

AJAX long polling

AJAX multipart streaming

Forever Iframe

JSONP Polling

WebSocket和HTTP和Socket

應(yīng)用層的協(xié)議,WebSocket在現(xiàn)代的軟件開發(fā)中被越來越多的實踐,和HTTP有一些相似的地方,而且有人也會把WebSocket和Socket混為一談,那么他們之間到底有什么異同呢?

WebSocket和HTTP

我們先看兩個協(xié)議的截圖來領(lǐng)會下。

相同點

都是基于TCP的應(yīng)用層協(xié)議。

都使用Request/Response模型進行連接的建立。

在連接的建立過程中對錯誤的處理方式相同,在這個階段WS可能返回和HTTP相同的返回碼。

都可以在網(wǎng)絡(luò)中傳輸數(shù)據(jù)。

不同點

WS使用HTTP來建立連接,但是定義了一系列新的header域,這些域在HTTP中并不會使用。

WS的連接不能通過中間人來轉(zhuǎn)發(fā),它必須是一個直接連接。

WS連接建立之后,通信雙方都可以在任何時刻向另一方發(fā)送數(shù)據(jù)。

WS連接建立之后,數(shù)據(jù)的傳輸使用幀來傳遞,不再需要Request消息。

WS的數(shù)據(jù)幀有序。

WebSocket和Socket

其實就像Java和JavaScript一樣,WebSocket和Socket并沒有太大的關(guān)系。

Socket可以有很多意思,和IT較相關(guān)的本意大致是指在端到端的一個連接中,這兩個端叫做Socket。對于IT從業(yè)者來說,它往往指的是TCP/IP網(wǎng)絡(luò)環(huán)境中的兩個連接端,大多數(shù)的API提供者(如操作系統(tǒng),JDK)往往會提供基于這種概念的接口,所以對于開發(fā)者來說也往往是在說一種編程概念。同時,操作系統(tǒng)中進程間通信也有Socket的概念,但這個Socket就不是基于網(wǎng)絡(luò)傳輸層的協(xié)議了。

Socket 其實并不是一個協(xié)議。它工作在 OSI 模型會話層(第5層),是為了方便大家直接使用更底層協(xié)議(一般是 TCP 或 UDP )而存在的一個抽象層。

Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設(shè)計模式中,Socket其實就是一個門面模式,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。

主機 A 的應(yīng)用程序要能和主機 B 的應(yīng)用程序通信,必須通過 Socket 建立連接,而建立 Socket 連接必須需要底層 TCP/IP 協(xié)議來建立 TCP 連接。建立 TCP 連接需要底層 IP 協(xié)議來尋址網(wǎng)絡(luò)中的主機。我們知道網(wǎng)絡(luò)層使用的 IP 協(xié)議可以幫助我們根據(jù) IP 地址來找到目標主機,但是一臺主機上可能運行著多個應(yīng)用程序,如何才能與指定的應(yīng)用程序通信就要通過 TCP 或 UPD 的地址也就是端口號來指定。這樣就可以通過一個 Socket 實例唯一代表一個主機上的一個應(yīng)用程序的通信鏈路了。

而 WebSocket 則不同,它是一個完整的 應(yīng)用層協(xié)議,包含一套標準的 API 。

所以,從使用上來說,WebSocket 更易用,而 Socket 更靈活。

瀏覽器支持

websocket api在瀏覽器端的廣泛實現(xiàn)似乎只是一個時間問題了, 值得注意的是服務(wù)器端沒有標準的api, 各個實現(xiàn)都有自己的一套api, 并且tcp也沒有類似的提案, 所以使用websocket開發(fā)服務(wù)器端有一定的風(fēng)險.可能會被鎖定在某個平臺上或者將來被迫升級。

本文相關(guān)的Demo已經(jīng)放在作者的Github上:小樓蘭的github

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/94888.html

相關(guān)文章

  • 基于 flask-socketio 的 CRUD 操作初探

    摘要:理解協(xié)議協(xié)議只能通過客戶端發(fā)起請求來與客戶端進行通訊這是一個缺陷。與協(xié)議有著良好的兼容性。以下的表格內(nèi)容顯示數(shù)據(jù)局里的內(nèi)容,每秒局部刷新一次表格內(nèi)容。歡迎大俠能夠給我的項目提出修改意見,先行感謝源碼下載參考基于的操作教程阮一峰 Flask 作為一個全棧架構(gòu),如果你只會 python,而不懂 javascript 的前端知識,似乎是無法支撐起你的 web 夢想的,比如,一個簡單的頁面 局...

    K_B_Z 評論0 收藏0
  • WebRTC 初探

    摘要:雖然是點對點通信,但還是需要服務(wù)器來初始化連接,并傳遞一些信息。服務(wù)器實現(xiàn)點對點通信的關(guān)鍵在于兩個瀏覽器之間能直接發(fā)送和接收數(shù)據(jù)包,但一般情況下,瀏覽器或手機都是通過路由器訪問,所以存在網(wǎng)絡(luò)地址轉(zhuǎn)換。 WebRTC 瀏覽器本身不支持相互之間直接建立信道進行通信,都是通過服務(wù)器進行中轉(zhuǎn)。比如現(xiàn)在有兩個客戶端,甲和乙,他們倆想要通信,首先需要甲和服務(wù)器、乙和服務(wù)器之間建立信道。甲給乙發(fā)送消...

    williamwen1986 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<