摘要:早期的輪詢是通過不斷自動刷新頁面而實現的。長輪詢的另一個問題是缺乏標準實現。服務器端接到這個請求后作出回應并不斷更新連接狀態以保證客戶端和服務器端的連接不過期。協議解析協議包含兩部分一部分是握手,一部分是數據傳輸。
Websocket是什么?
Websocket是一個因為應用場景越來越復雜而提出的,針對瀏覽器和web服務器之間雙向持續通信而設計,而且優雅地兼容HTTP的協議(我猜想:同時因為建立在HTTP上,也可以利用好HTTP原有的基礎比如basic認證)。
網絡模型結構上來說呢,
WebSocket 實際上指的是一種協議,與我們熟知的Http協議是同等的一個網絡協議。用網絡模型結構來解釋的話,WebSocket和Http協議都屬于應用層協議,兩者都基于傳輸層的TCP協議。
websocket協議本質上是一個基于tcp的協議,是先通過HTTP/HTTPS協議發起一條特殊的http請求進行握手后創建一個用于交換數據的TCP連接,此后服務端與客戶端通過此TCP連接進行實時通信。
Websocket的作用和優點? 非WebSocket的實時信息傳遞技術?與http協議的關系:
WebSocket不是Http協議,Http協議只是被WebSocket使用來建立連接,連接建立了以后客戶端與服務器的雙向通信就與Http無關了。
借用了http的協議完成握手的一個新協議,可以說是基于http協議,可以說是http協議的一種補充,也可以說與http協議毫無關系
WebSocket 是什么原理?為什么可以實現持久連接? - 知乎
輪詢
輪詢是由客戶端定時向服務端發起查詢數據的請求的一種實現方式。早期的輪詢是通過不斷自動刷新頁面而實現的。
在特定的時間間隔(例如1秒),由瀏覽器向服務器發出一個Http Request,然后服務器返回最新的數據給客戶端瀏覽器,從而給出一種服務端實時推送的假象。由于Http Request的Header(請求頭)很長,而傳輸的數據可能很短就只占一點點,每次請求消耗的帶寬和服務器資源大部分都消耗在Header上。(想想ajax技術和全頁面傳值的資源消耗)
ajax輪詢
ajax輪詢,又被稱為Comet,由客戶端不停地請求服務器端,查詢有沒有新消息,然后再由服務器返回結果;是輪詢的一種優化,實現了無刷新更新數據,并且不用傳遞header頭的信息,傳遞內容更少。
但本質上這些方式均是客戶端定時輪詢服務端,這種方式的最顯著的缺點是如果客戶端數量龐大并且定時輪詢間隔較短服務端將承受響應這些客戶端海量請求的巨大的壓力。
長輪詢
長輪詢(long polling)是另一種流行的通信方法,客戶端向服務器請求信息,并在設定的時間段內打開一個連接。服務器如果沒有任何信息,會保持請求打開,直到有客戶端可用的信息,或者直到指定的超時時間用完為止。這時,客戶端重新向服務器請求信息。長輪詢也稱作Comet(前面已經提到過)或者反向AJAX。Comet延長HTTP響應的完成,直到服務器有需要發送給客戶端的內容,這種技術常常稱作“掛起GET”或“擱置POST”。重要的是要知道,當信息量很大時,長輪詢相對于傳統輪詢并沒有明顯的性能優勢,因為客戶端必須頻繁地重連到服務器以讀取新信息,造成網絡的表現和快速輪詢相同。長輪詢的另一個問題是缺乏標準實現。
長輪詢其實原理跟ajax輪詢差不多,都是采用輪詢的方式,不過采取的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,通過一次請求,詢問服務器有沒有新消息更新,如果沒有新消息時,會保持長連接,就一直不返回Response給客戶端。直到有消息才返回,返回完之后,客戶端再次建立連接,周而復始。
在數據更新不夠頻繁的情況下,使用輪詢方法獲取數據時客戶端經常會得到沒有數據的響應,顯然這樣的輪詢是一個浪費網絡資源的無效的輪詢。長輪詢則是針對普通輪詢的這種缺陷的一種改進方案,其具體實現方式是如果當前請求沒有數據可以返回,則繼續保持當前請求的網絡連接狀態,直到服務端有數據可以返回或者連接超時。長輪詢通過這種方式減少了客戶端與服務端交互的次數,避免了一些無謂的網絡連接。但是如果數據變更較為頻繁,則長輪詢方式與普通輪詢在性能上并無顯著差異。同時,增加連接的等待時間,往往意味著并發性能的下降。
長輪詢雖然降低了服務器的負載,但是需要服務器有很高的并發能力才可以。
而目前處理高并發的模型基本都是異步非阻塞的模型(比如nginx)。
既想阻塞,又想高并發,幾乎不可能。
流
傳統方法的缺點?所謂流是指客戶端在頁面之下向服務端發起一個長連接請求,服務端收到這個請求后響應它并不斷更新連接狀態,以確保這個連接在客戶端與服務端之間一直有效。服務端可以通過這個連接將數據主動推送到客戶端。顯然,這種方案實現起來相對比較麻煩,而且可能被防火墻阻斷。
在流化技術中,客戶端發送一個請求,服務器發送并維護一個持續更新和保持打開(可以是無限或者規定的時間段)的開放響應。每當服務器有需要交付給客戶端的信息時,它就更新響應。看起來,流化是能夠適應不可預測的信息交付的極佳方案,但是服務器從不發出完成HTTP響應的請求,從而使連接一直保持打開。在這種情況下,代理和防火墻可能緩存響應,導致信息交付的延遲增加。因此,許多流化的嘗試對于存在防火墻和代理的網絡是不友好的。
流技術方案通常就是在客戶端的頁面使用一個隱藏的窗口向服務端發出一個長連接的請求。服務器端接到這個請求后作出回應并不斷更新連接狀態以保證客戶端和服務器端的連接不過期。通過這種機制可以將服務器端的信息源源不斷地推向客戶端。這種機制在用戶體驗上有一點問題,需要針對不同的瀏覽器設計不同的方案來改進用戶體驗,同時這種機制在并發比較大的情況下,對服務器端的資源是一個極大的考驗。
Web 通信 之 長連接、長輪詢(long polling) - hoojo - 博客園
上述方法提供了近乎實時的通信,
但是它們也涉及HTTP請求和響應首標,
包含了許多附加和不必要的首標數據與延遲。
此外,在每一種情況下,客戶端都必須等待請求返回,才能發出后續的請求,而這顯著地增加了延遲。
以上四種方法的后三種呢,都實現了真正的雙工通信,但都是單向鏈接,需要被動的請求服務器,而不是由服務器自動發給客戶端。(還是在代碼層面上下功夫,但是這種情況下,明顯需要從協議層去想辦法)
首先就是非常消耗資源,不斷地建立HTTP連接,然后等待服務端處理,可以體現HTTP協議的另外一個特點,被動性。其次呢,
ajax輪詢需要服務器有很快的處理速度和資源,
長輪詢需要有很高的并發,也就是同時處理請求的能力
基于此,websocket出現了,它解決了http不利于這種場景下(聊天,視頻...)的兩個問題:
http協議是一個無狀態的,被動的協議(不持久,服務端無法主動發送信息給客戶端)
Websocket只需要一次HTTP握手,所以說整個通訊過程是建立在一次連接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反復解析HTTP協議,還要查看identity info的信息。
同時由客戶主動詢問,轉換為服務器(推送)有信息的時候就發送(當然客戶端還是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不需要占用本身速度就慢的客服(Handler)了
所以,,,
Websocket能更好的實現雙向通信且節省服務器資源和帶寬。
wensocket協議包含兩部分:一部分是“握手”,一部分是“數據傳輸”。為了便于演示,我們采用swoole建立一個websocket服務器來演示。
握手部分:Websocket協議之握手連接 - Oshyn —— 樂而學,學而樂 - CSDN博客
①客戶端向服務端發起連接請求
如圖,我們在請求服務器的時候,發送了這樣的request header。
下面我們就一些比較重要的字段信息進行說明:
* Connection:Upgrade #通知服務器協議升級 Upgrade:websocket #協議升級為websocket協議 * Host:0.0.0.0:9501 #升級協議的服務主機:端口地址 * Sec-WebSocket-Key:K8o1cNIxO2pR6inTIDBSgg== #傳輸給服務器的key * Sec-WebSocket-Version:13 #websocket協議版本13
Sec-WebSocket-Key有什么用呢?客戶端將這個key發送給服務器,服務器將這個key進行處理,將處理后的key返回給客戶端,客戶端根據這個key是否正確來判斷是否建立連接。
②:服務端返回握手應答
如圖,我們看到websocket協議狀態碼是101.
101表示協議切換成功。
我們查看websocket的response header。如圖:
下面解釋下reponse header字段的含義
* Connection:Upgrade #協議升級成功 * Sec-WebSocket-Accept:GnoYH/ip/ZMh+a5rX5P/YR6e68g= #服務端處理之后的key * Sec-WebSocket-Version:13#websocket 協議版本號 * Upgrade:websocket#協議升級為websocket
至此,websocket握手成功!下面就盡情的傳輸數據吧!
數據傳輸部分:數據傳輸需要客戶端,非websocket客戶端不能與websocket服務器通信,那么怎么實現websocket客戶端呢?
* Chrome/Firefox/高版本IE/Safari等瀏覽器內置了JS語言的WebSocket客戶端 * 可以使用一些擴展來實現websocket客戶端。如php的swoole、workerman。怎么使用websocket實現聊天室? 可以參考的DEMO
PHP源碼及DEMO:
洞悉/websocket - 碼云
swoole 服務端120行代碼構建一個websocket 聊天室. - 個人文章 - SegmentFault
基于swoole和websocket的直播攝像頭的demo
NodeJS實現Websocket聊天室:
利用express+socket.io實現一個簡易版聊天室 - zp的筆記 - SegmentFault
JAVA實現websocket聊天室:
websocket筆記以及一個微型聊天室例子 - niiiu的web雜談 - SegmentFault
Chrome下會報這個
WebSocket connection to "ws://127.0.0.1:8000/" failed: Error in
connection establishment: net::ERR_CONNECTION_REFUSED
Firefox下會報這個
Firefox 無法建立到 ws://... 服務器的連接;
那么如何解決呢?
目前來看,主要是三個方面的問題,
* URL路徑,這個要注意一下文件名或者路徑是不是有問題; * 其次,看下瀏覽器的支持問題,是否有需要開啟的配置; * 最后,看看是不是websocket的進程是不是不在運行中,否則瀏覽器會連接不上;
第二種問題很容易解決了,about:config里搜websocket,檢查是否有錯誤的配置項。
這里著重說下最后一種問題,
運行程序之前,要先在服務器跑一下他的php文件
在命令行cd到文件夾下php websocket.php,報的這個錯
PHP Fatal error: Uncaught Error: Call to undefined function socket_create() in E:phpStudyWWWMonth10websocketwebsocket.php:87 Stack trace: #0 E:phpStudyWWWMonth10websocketwebsocket.php(19): Sock->WebSocket("127.0.0.1", 8000) #1 E:phpStudyWWWMonth10websocketwebsocket.php(5): Sock->__construct("127.0.0.1", 8000) #2 {main} thrown in E:phpStudyWWWMonth10websocketwebsocket.php on line 87 Fatal error: Uncaught Error: Call to undefined function socket_create() in E:phpStudyWWWMonth10websocketwebsocket.php:87 Stack trace: #0 E:phpStudyWWWMonth10websocketwebsocket.php(19): Sock->WebSocket("127.0.0.1", 8000) #1 E:phpStudyWWWMonth10websocketwebsocket.php(5): Sock->__construct("127.0.0.1", 8000) #2 {main} thrown in E:phpStudyWWWMonth10websocketwebsocket.php on line 87
注意要開啟websocket的php拓展,解決方法如下:
遭遇了"Call to undefined function socket_create()" - 可視化空間 - ITeye博客
找到php.ini,看 extension=php_gd2.dll 和 extension=php_sockets.dll 擴展是否打開;
看phpInfo()顯示的內容里,socket模塊是否為enable;
Websocket的應用場景?我檢查了一下,發現都是符合的。但錯誤仍然出現?怎么回事呢?
后來我才發現,原來是我在phpInfo()里看到的和在cmd窗口里使用的php不是同一個東西。
原因是我多次安裝過php. 先前的php在系統的環境變量里面注冊了path。所以在cmd窗口里使用的是以前的php.
而在phpInfo()里顯示的是現在的php的設置。解決的辦法很簡單了,就把系統環境變量里的path里,指向老的Php的路徑改為指向正在使用的Php的路徑。這樣在cmd里的php和在瀏覽器里的php就是同一個東西了。
決定手頭的工作是否需要使用WebSocket技術的方法很簡單:
* 你的應用提供多個用戶相互交流嗎? * 你的應用是展示服務器端經常變動的數據嗎?
如果你的回答是肯定的,那么請考慮使用WebSocket。如果你仍然不確定,并想要更多的靈感,這有一些殺手锏的案例。
1.社交訂閱
對社交類的應用的一個裨益之處就是能夠即時的知道你的朋友正在做什么。雖然聽起來有點可怕,但是我們都喜歡這樣做。你不會想要在數分鐘之后才能知道一個家庭成員在餡餅制作大賽獲勝或者一個朋友訂婚的消息。你是在線的,所以你的訂閱的更新應該是實時的。
2.多玩家游戲
網絡正在迅速轉變為游戲平臺。在不使用插件(我指的是Flash)的情況下,網絡開發者現在可以在瀏覽器中實現和體驗高性能的游戲。無論你是在處理DOM元素、CSS動畫,HTML5的canvas或者嘗試使用WebGL,玩家之間的互動效率是至關重要的。我不想在我扣動扳機之后,我的對手卻已經移動位置。
3.協同編輯/編程
我們生活在分布式開發團隊的時代。平時使用一個文檔的副本就滿足工作需求了,但是你最終需要有一個方式來合并所有的編輯副本。版本控制系統,比如Git能夠幫助處理某些文件,但是當git發現一個它不能解決的沖突時,你仍然需要去跟蹤人們的修改歷史。通過一個協同解決方案,比如WebSocket,我們能夠工作在同一個文檔,從而省去所有的合并版本。這樣會很容易看出誰在編輯什么或者你在和誰同時在修改文檔的同一部分。
4.點擊流數據
分析用戶與你網站的互動是提升你的網站的關鍵。HTTP的開銷讓我們只能優先考慮和收集最重要的數據部分。然后,經過六個月的線下分析,我們意識到我們應該收集一個不同的判斷標準——一個看起來不是那么重要但是現在卻影響了一個關鍵的決定。與HTTP請求的開銷方式相比,使用Websocket,你可以由客戶端發送不受限制的數據。想要在除頁面加載之外跟蹤鼠標的移動?只需要通過WebSocket連接發送這些數據到服務器,并存儲在你喜歡的NoSQL數據庫中就可以了(MongoDB是適合記錄這樣的事件的)。現在你可以通過回放用戶在頁面的動作來清楚的知道發生了什么。
5.股票基金報價
金融界瞬息萬變——幾乎是每毫秒都在變化。我們人類的大腦不能持續以那樣的速度處理那么多的數據,所以我們寫了一些算法來幫我們處理這些事情。雖然你不一定是在處理高頻的交易,但是,過時的信息也只能導致損失。當你有一個顯示盤來跟蹤你感興趣的公司時,你肯定想要隨時知道他們的價值,而不是10秒前的數據。使用WebSocket可以流式更新這些數據變化而不需要等待。
6.體育實況更新
現在我們開始討論一個讓人們激情澎湃的愚蠢的東西——體育。我不是運動愛好者,但是我知道運動迷們想要什么。當愛國者在打比賽的時候,我的妹夫將會沉浸于這場比賽中而不能自拔。那是一種瘋狂癡迷的狀態,完全發自內心的。我雖然不理解這個,但是我敬佩他們與運動之間的這種強烈的聯系,所以,最后我能做的就是給他的體驗中降低延遲。如果你在你的網站應用中包含了體育新聞,WebSocket能夠助力你的用戶獲得實時的更新。
7.多媒體聊天視頻會議并不能代替和真人相見,但當你不能在同一個屋子里見到你談話的對象時,視頻會議是個不錯的選擇。盡管視頻會議私有化做的“不錯”,但其使用還是很繁瑣。我可是開放式網絡的粉絲,所以用WebSockets getUserMedia API和html5音視頻元素明顯是個不錯的選擇。WebRTC的出現順理成章的成為我剛才概括的組合體,它看起來很有希望,但其缺乏目前瀏覽器的支持,所以就取消了它成為候選人的資格。
8.基于位置的應用
越來越多的開發者借用移動設備的GPS功能來實現他們基于位置的網絡應用。如果你一直記錄用戶的位置(比如運行應用來記錄運動軌跡),你可以收集到更加細致化的數據。如果你想實時的更新網絡數據儀表盤(可以說是一個監視運動員的教練),HTTP協議顯得有些笨拙。借用WebSocket TCP鏈接可以讓數據飛起來。
9.在線教育上學花費越來越貴了,但互聯網變得更快和更便宜。在線教育是學習的不錯方式,尤其是你可以和老師以及其他同學一起交流。很自然,WebSockets是個不錯的選擇,可以多媒體聊天、文字聊天以及其它優勢如與別人合作一起在公共數字黑板上畫畫...
【技術分享】WebSocket漏洞與防護詳解_黑客技術
一個socket是一次網絡通信中的一個端點。socket總是分為兩部分:一個IP地址和一個端口。
例如:當您訪問www.securelayer7.net時,你的計算機和網站的服務器正在使用socket(端點)進行通信。網站的端點將是:www.securelayer7.net:80,你的計算機的端點將是你的IP地址,后跟任何隨機端口號,如192.168.0.111:6574
跨站websocket劫持
網絡敏感信息泄露
DDOS攻擊(默認情況下,WebSockets允許無限制的連接導致DOS)
WebSocket初探
WebSocket實現原理
WebSocket 是什么原理?如何實現消息實時推送?
WebSocket原理
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/23218.html
摘要:握手客戶端向服務端發起連接請求如圖,我們在請求服務器的時候,發送了這樣的。如圖下面解釋下字段的含義協議升級成功服務端處理之后的協議版本號協議升級為至此,握手成功下面就盡情的傳輸數據吧數據傳輸數據傳輸需要客戶端,沒什么好說的了。 一、閱前熱身 什么是keep-alive 1、keep-alive只是客戶端的一種建議 我們打開百度首頁,進一步查看header。 showImg(https:...
摘要:一協議概述協議允許不受信用的客戶端代碼在可控的網絡環境中控制遠程主機。該協議包含一個握手和一個基本消息分幀分層通過。該協議包括兩個方面,握手鏈接和數據傳輸。二注意事項很多人可能只是到,但事實上協議地址是可以加和的。 本文同步自我的博客園:http://hustskyking.cnblogs.com P.S:文章代碼格式錯亂,也不知道是什么原因,還望@segmentFault的兄弟看下~...
摘要:下表給出了相對于同源檢測的結果跨域解決方法由兩部分組成回調函數和數據。回調函數時當響應到來是應該在頁面中調用的函數,名字一般在請求中指定。 何為跨域? 一般情況下,XMLHttpRequest(XHR)對象只能訪問與包含它的頁面位于同一個域中的資源,這種安全策略可以預防某些惡意行為,即通常所說的同源策略。 只要協議、域名、端口號有任何一個不同,都會被當成不同的域。 下表給出了相對于 h...
摘要:如何解決跨域問題跨域原因由于瀏覽器的同源策略限制,只允許請求當前源域名協議端口的資源。同源策略同源策略是客戶端腳本尤其是的重要的安全度量標準。同源策略指的是協議,域名,端口相同,同源策略是一種安全協議。狀態表示客戶端已發送報文。 如何解決跨域問題: 跨域原因:由于瀏覽器的同源策略限制,XmlHttpRequest只允許請求當前源(域名、協議、端口)的資源。在腳本中發起HTTP請求,出于...
閱讀 924·2021-10-27 14:14
閱讀 1749·2021-10-11 10:59
閱讀 1321·2019-08-30 13:13
閱讀 3157·2019-08-29 15:17
閱讀 2756·2019-08-29 13:48
閱讀 494·2019-08-26 13:36
閱讀 2087·2019-08-26 13:25
閱讀 862·2019-08-26 12:24