国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

為什么我們要熟悉這些通信協(xié)議? 【精讀】

zhunjiee / 2839人閱讀

摘要:服務(wù)器端收到報(bào)文,回應(yīng)一個(gè)報(bào)文,進(jìn)入狀態(tài)。接收到這個(gè)的對(duì)端執(zhí)行被動(dòng)關(guān)閉,這個(gè)由確認(rèn)。在連接建立后,我們可以有多種協(xié)議的方式通信交換數(shù)據(jù)最古老的方式一早先的版本,是一種無狀態(tài)無連接的應(yīng)用層協(xié)議。

打個(gè)廣告,歡迎加入我們的前端開發(fā)交流群:

微信群:

QQ群

前端的最重要的基礎(chǔ)知識(shí)點(diǎn)是什么?

原生javaScriptHTML,CSS.

Dom操作

EventLoop和渲染機(jī)制

各類工程化的工具原理以及使用,根據(jù)需求定制編寫插件和包。(webpack的plugin和babel的預(yù)設(shè)包)

數(shù)據(jù)結(jié)構(gòu)和算法(特別是IM以及超大型高并發(fā)網(wǎng)站應(yīng)用等,例如B站

最后便是通信協(xié)議

在使用某個(gè)技術(shù)的時(shí)候,一定要去追尋原理和底層的實(shí)現(xiàn),長(zhǎng)此以往堅(jiān)持,只要自身底層的基礎(chǔ)扎實(shí),無論技術(shù)怎么變化,學(xué)習(xí)起來都不會(huì)太累,總的來說就是拒絕5分鐘技術(shù)
從輸入一個(gè)url地址,到顯示頁(yè)面發(fā)生了什么出發(fā):

1.瀏覽器向 DNS 服務(wù)器請(qǐng)求解析該 URL 中的域名所對(duì)應(yīng)的 IP 地址;

2.建立TCP連接(三次握手);

3.瀏覽器發(fā)出讀取文件(URL 中域名后面部分對(duì)應(yīng)的文件)的HTTP 請(qǐng)求,該請(qǐng)求報(bào)文作為 TCP 三次握手的第三個(gè)報(bào)文的數(shù)據(jù)發(fā)送給服務(wù)器;

4.服務(wù)器對(duì)瀏覽器請(qǐng)求作出響應(yīng),并把對(duì)應(yīng)的 html 文本發(fā)送給瀏覽器;

5.瀏覽器將該 html 文本并顯示內(nèi)容;

6.釋放 TCP連接(四次揮手);

目前常見的通信協(xié)議都是建立在TCP鏈接之上 那么什么是TCP TCP是因特網(wǎng)中的傳輸層協(xié)議,使用三次握手協(xié)議建立連接。當(dāng)主動(dòng)方發(fā)出SYN連接請(qǐng)求后,等待對(duì)方回答
TCP三次握手的過程如下:

客戶端發(fā)送SYN報(bào)文給服務(wù)器端,進(jìn)入SYN_SEND狀態(tài)。

服務(wù)器端收到SYN報(bào)文,回應(yīng)一個(gè)SYN(SEQ=y)ACK(ACK=x+1)報(bào)文,進(jìn)入SYN_RECV狀態(tài)。

客戶端收到服務(wù)器端的SYN報(bào)文,回應(yīng)一個(gè)ACK(ACK=y+1)報(bào)文,進(jìn)入Established狀態(tài)。

三次握手完成,TCP客戶端和服務(wù)器端成功地建立連接,可以開始傳輸數(shù)據(jù)了。

如圖所示:

TCP的四次揮手:

建立一個(gè)連接需要三次握手,而終止一個(gè)連接要經(jīng)過四次握手,這是由TCP的半關(guān)閉(half-close)造成的。具體過程如下圖所示。

某個(gè)應(yīng)用進(jìn)程首先調(diào)用close,稱該端執(zhí)行“主動(dòng)關(guān)閉”(active close)。該端的TCP于是發(fā)送一個(gè)FIN分節(jié),表示數(shù)據(jù)發(fā)送完畢。

接收到這個(gè)FIN的對(duì)端執(zhí)行 “被動(dòng)關(guān)閉”(passive close),這個(gè)FIN由TCP確認(rèn)。

注意:FIN的接收也作為一個(gè)文件結(jié)束符(end-of-file)傳遞給接收端應(yīng)用進(jìn)程,放在已排隊(duì)等候該應(yīng)用進(jìn)程接收的任何其他數(shù)據(jù)之后,因?yàn)椋現(xiàn)IN的接收意味著接收端應(yīng)用進(jìn)程在相應(yīng)連接上再無額外數(shù)據(jù)可接收。

一段時(shí)間后,接收到這個(gè)文件結(jié)束符的應(yīng)用進(jìn)程將調(diào)用close關(guān)閉它的套接字。這導(dǎo)致它的TCP也發(fā)送一個(gè)FIN。

接收這個(gè)最終FIN的原發(fā)送端TCP(即執(zhí)行主動(dòng)關(guān)閉的那一端)確認(rèn)這個(gè)FIN。 [3]

既然每個(gè)方向都需要一個(gè)FIN和一個(gè)ACK,因此通常需要4個(gè)分節(jié)。

特別提示: SYN報(bào)文用來通知,FIN報(bào)文是用來同步的

以上就是面試官常問的三次握手,四次揮手,但是這不僅僅面試題,上面僅僅答到了一點(diǎn)皮毛,學(xué)習(xí)這些是為了讓我們后續(xù)方便了解他的優(yōu)缺點(diǎn)。
TCP連接建立后,我們可以有多種協(xié)議的方式通信交換數(shù)據(jù): 最古老的方式一:http 1.0

早先1.0的HTTP版本,是一種無狀態(tài)、無連接的應(yīng)用層協(xié)議。

HTTP1.0規(guī)定瀏覽器和服務(wù)器保持短暫的連接,瀏覽器的每次請(qǐng)求都需要與服務(wù)器建立一個(gè)TCP連接,服務(wù)器處理完成后立即斷開TCP連接(無連接),服務(wù)器不跟蹤每個(gè)客戶端也不記錄過去的請(qǐng)求(無狀態(tài))。

這種無狀態(tài)性可以借助cookie/session機(jī)制來做身份認(rèn)證和狀態(tài)記錄。而下面兩個(gè)問題就比較麻煩了。

首先,無連接的特性導(dǎo)致最大的性能缺陷就是無法復(fù)用連接。每次發(fā)送請(qǐng)求的時(shí)候,都需要進(jìn)行一次TCP的連接,而TCP的連接釋放過程又是比較費(fèi)事的。這種無連接的特性會(huì)使得網(wǎng)絡(luò)的利用率非常低。

其次就是隊(duì)頭阻塞(headoflineblocking)。由于HTTP1.0規(guī)定下一個(gè)請(qǐng)求必須在前一個(gè)請(qǐng)求響應(yīng)到達(dá)之前才能發(fā)送。假設(shè)前一個(gè)請(qǐng)求響應(yīng)一直不到達(dá),那么下一個(gè)請(qǐng)求就不發(fā)送,同樣的后面的請(qǐng)求也給阻塞了。

Http 1.0的致命缺點(diǎn),就是無法復(fù)用TCP連接和并行發(fā)送請(qǐng)求,這樣每次一個(gè)請(qǐng)求都需要三次握手,而且其實(shí)建立連接和釋放連接的這個(gè)過程是最耗時(shí)的,傳輸數(shù)據(jù)相反卻不那么耗時(shí)。還有本地時(shí)間被修改導(dǎo)致響應(yīng)頭expires的緩存機(jī)制失效的問題~(后面會(huì)詳細(xì)講)

常見的請(qǐng)求報(bào)文~

于是出現(xiàn)了Http 1.1,這也是技術(shù)的發(fā)展必然結(jié)果~

Http 1.1出現(xiàn),繼承了Http1.0的優(yōu)點(diǎn),也克服了它的缺點(diǎn),出現(xiàn)了keep-alive這個(gè)頭部字段,它表示會(huì)在建立TCP連接后,完成首次的請(qǐng)求,并不會(huì)立刻斷開TCP連接,而是保持這個(gè)連接狀態(tài)~進(jìn)而可以復(fù)用這個(gè)通道

Http 1.1并且支持請(qǐng)求管道化,“并行”發(fā)送請(qǐng)求,但是這個(gè)并行,也不是真正意義上的并行,而是可以讓我們把先進(jìn)先出隊(duì)列從客戶端(請(qǐng)求隊(duì)列)遷移到服務(wù)端(響應(yīng)隊(duì)列)

例如:客戶端同時(shí)發(fā)了兩個(gè)請(qǐng)求分別來獲取html和css,假如說服務(wù)器的css資源先準(zhǔn)備就緒,服務(wù)器也會(huì)先發(fā)送html再發(fā)送css。

B站首頁(yè),就有keep-alive,因?yàn)樗麄円灿?b>IM的成分在里面。需要大量復(fù)用TCP連接~

HTTP1.1好像還是無法解決隊(duì)頭阻塞的問題

實(shí)際上,現(xiàn)階段的瀏覽器廠商采取了另外一種做法,它允許我們打開多個(gè)TCP的會(huì)話。也就是說,上圖我們看到的并行,其實(shí)是不同的TCP連接上的HTTP請(qǐng)求和響應(yīng)。這也就是我們所熟悉的瀏覽器對(duì)同域下并行加載6~8個(gè)資源的限制。而這,才是真正的并行!
Http 1.1的致命缺點(diǎn):

1.明文傳輸

2.其實(shí)還是沒有解決無狀態(tài)連接的

3.當(dāng)有多個(gè)請(qǐng)求同時(shí)被掛起的時(shí)候 就會(huì)擁塞請(qǐng)求通道,導(dǎo)致后面請(qǐng)求無法發(fā)送

4.臃腫的消息首部:HTTP/1.1能壓縮請(qǐng)求內(nèi)容,但是消息首部不能壓縮;在現(xiàn)今請(qǐng)求中,消息首部占請(qǐng)求絕大部分(甚至是全部)也較為常見.

我們也可以用dns-prefetch和 preconnect tcp來優(yōu)化~

Tip: webpack可以做任何事情,這些都可以用插件實(shí)現(xiàn)

基于這些缺點(diǎn),出現(xiàn)了Http 2.0 相較于HTTP1.1,HTTP2.0的主要優(yōu)點(diǎn)有采用二進(jìn)制幀封裝,傳輸變成多路復(fù)用,流量控制算法優(yōu)化,服務(wù)器端推送,首部壓縮,優(yōu)先級(jí)等特點(diǎn)。 HTTP1.x的解析是基于文本的,基于文本協(xié)議的格式解析存在天然缺陷,文本的表現(xiàn)形式有多樣性,要做到健壯性考慮的場(chǎng)景必然很多。而HTTP/2會(huì)將所有傳輸?shù)男畔⒎指顬楦〉南⒑蛶缓蟛捎枚M(jìn)制的格式進(jìn)行編碼,HTTP1.x的頭部信息會(huì)被封裝到HEADER frame,而相應(yīng)的RequestBody則封裝到DATAframe里面。不改動(dòng)HTTP的語(yǔ)義,使用二進(jìn)制編碼,實(shí)現(xiàn)方便且健壯。 多路復(fù)用

所有的請(qǐng)求都是通過一個(gè) TCP 連接并發(fā)完成。HTTP/1.x 雖然通過 pipeline 也能并發(fā)請(qǐng)求,但是多個(gè)請(qǐng)求之間的響應(yīng)會(huì)被阻塞的,所以 pipeline 至今也沒有被普及應(yīng)用,而 HTTP/2 做到了真正的并發(fā)請(qǐng)求。同時(shí),流還支持優(yōu)先級(jí)和流量控制。當(dāng)流并發(fā)時(shí),就會(huì)涉及到流的優(yōu)先級(jí)和依賴。即:HTTP2.0對(duì)于同一域名下所有請(qǐng)求都是基于流的,不管對(duì)于同一域名訪問多少文件,也只建立一路連接。優(yōu)先級(jí)高的流會(huì)被優(yōu)先發(fā)送。圖片請(qǐng)求的優(yōu)先級(jí)要低于 CSS 和 SCRIPT,這個(gè)設(shè)計(jì)可以確保重要的東西可以被優(yōu)先加載完

流量控制

TCP協(xié)議通過sliding window的算法來做流量控制。發(fā)送方有個(gè)sending window,接收方有receive window。http2.0的flow control是類似receive window的做法,數(shù)據(jù)的接收方通過告知對(duì)方自己的flow window大小表明自己還能接收多少數(shù)據(jù)。只有Data類型的frame才有flow control的功能。對(duì)于flow control,如果接收方在flow window為零的情況下依然更多的frame,則會(huì)返回block類型的frame,這張場(chǎng)景一般表明http2.0的部署出了問題。

服務(wù)器端推送

服務(wù)器端的推送,就是服務(wù)器可以對(duì)一個(gè)客戶端請(qǐng)求發(fā)送多個(gè)響應(yīng)。除了對(duì)最初請(qǐng)求的響應(yīng)外,服務(wù)器還可以額外向客戶端推送資源,而無需客戶端明確地請(qǐng)求。當(dāng)瀏覽器請(qǐng)求一個(gè)html,服務(wù)器其實(shí)大概知道你是接下來要請(qǐng)求資源了,而不需要等待瀏覽器得到html后解析頁(yè)面再發(fā)送資源請(qǐng)求。

首部壓縮

HTTP 2.0 在客戶端和服務(wù)器端使用“首部表”來跟蹤和存儲(chǔ)之前發(fā)送的鍵-值對(duì),對(duì)于相同的數(shù)據(jù),不再通過每次請(qǐng)求和響應(yīng)發(fā)送;通信期間幾乎不會(huì)改變的通用鍵-值對(duì)(用戶代理、可接受的媒體類型,等等)只 需發(fā)送一次。事實(shí)上,如果請(qǐng)求中不包含首部(例如對(duì)同一資源的輪詢請(qǐng)求),那么 首部開銷就是零字節(jié)。此時(shí)所有首部都自動(dòng)使用之前請(qǐng)求發(fā)送的首部。

如果首部發(fā)生變化了,那么只需要發(fā)送變化了數(shù)據(jù)在Headers幀里面,新增或修改的首部幀會(huì)被追加到“首部表”。首部表在 HTTP 2.0 的連接存續(xù)期內(nèi)始終存在,由客戶端和服務(wù)器共同漸進(jìn)地更新 。

本質(zhì)上,當(dāng)然是為了減少請(qǐng)求啦,通過多個(gè)js或css合并成一個(gè)文件,多張小圖片拼合成Sprite圖,可以讓多個(gè)HTTP請(qǐng)求減少為一個(gè),減少額外的協(xié)議開銷,而提升性能。當(dāng)然,一個(gè)HTTP的請(qǐng)求的body太大也是不合理的,有個(gè)度。文件的合并也會(huì)犧牲模塊化和緩存粒度,可以把“穩(wěn)定”的代碼or 小圖 合并為一個(gè)文件or一張Sprite,讓其充分地緩存起來,從而區(qū)分開迭代快的文件。

Demo的性能對(duì)比:

Http的那些致命缺陷,并沒有完全解決,于是有了https,也是目前應(yīng)用最廣的協(xié)議之一 HTTP+ 加密 + 認(rèn)證 + 完整性保護(hù) =HTTPS ? 可以這樣認(rèn)為~HTTP 加上加密處理和認(rèn)證以及完整性保護(hù)后即是 HTTPS

如果在 HTTP 協(xié)議通信過程中使用未經(jīng)加密的明文,比如在 Web 頁(yè)面中輸入信用卡號(hào),如果這條通信線路遭到竊聽,那么信用卡號(hào)就暴露了。

另外,對(duì)于 HTTP 來說,服務(wù)器也好,客戶端也好,都是沒有辦法確認(rèn)通信方的。

因?yàn)楹苡锌赡懿⒉皇呛驮绢A(yù)想的通信方在實(shí)際通信。并且還需要考慮到接收到的報(bào)文在通信途中已經(jīng)遭到篡改這一可能性。

為了統(tǒng)一解決上述這些問題,需要在 HTTP 上再加入加密處理和認(rèn)證等機(jī)制。我們把添加了加密及認(rèn)證機(jī)制的 HTTP 稱為 HTTPS

不加密的重要內(nèi)容被wireshark這類工具抓到包,后果很嚴(yán)重~
HTTPS 是身披 SSL 外殼的 HTTP

HTTPS 并非是應(yīng)用層的一種新協(xié)議。只是 HTTP 通信接口部分用 SSL(SecureSocket Layer)和 TLS(Transport Layer Security)協(xié)議代替而已。

通常,HTTP 直接和 TCP 通信。

當(dāng)使用 SSL 時(shí),則演變成先和 SSL 通信,再由 SSL和 TCP 通信了。簡(jiǎn)言之,所謂 HTTPS,其實(shí)就是身披 SSL 協(xié)議這層外殼的HTTP。

在采用 SSL 后,HTTP 就擁有了 HTTPS 的加密、證書和完整性保護(hù)這些功能。SSL 是獨(dú)立于 HTTP 的協(xié)議,所以不光是 HTTP 協(xié)議,其他運(yùn)行在應(yīng)用層的 SMTP和 Telnet 等協(xié)議均可配合 SSL 協(xié)議使用。可以說 SSL 是當(dāng)今世界上應(yīng)用最為廣泛的網(wǎng)絡(luò)安全術(shù)。

相互交換密鑰的公開密鑰加密技術(shù) -----對(duì)稱加密

在對(duì) SSL 進(jìn)行講解之前,我們先來了解一下加密方法。SSL 采用一種叫做公開密鑰加密(Public-key cryptography)的加密處理方式。

近代的加密方法中加密算法是公開的,而密鑰卻是保密的。通過這種方式得以保持加密方法的安全性。

加密和解密都會(huì)用到密鑰。沒有密鑰就無法對(duì)密碼解密,反過來說,任何人只要持有密鑰就能解密了。如果密鑰被攻擊者獲得,那加密也就失去了意義。

https://blog.csdn.net/ituling..., Https加密篇幅太長(zhǎng),這篇文章寫得很好,大家可以去看看。

HTTPS 采用混合加密機(jī)制

HTTPS 采用共享密鑰加密和公開密鑰加密兩者并用的混合加密機(jī)制。

但是公開密鑰加密與共享密鑰加密相比,其處理速度要慢。所以應(yīng)充分利用兩者各自的優(yōu)勢(shì),將多種方法組合起來用于通信。在交換密鑰環(huán)節(jié)使用公開密鑰加密方式,之后的建立通信交換報(bào)文階段則使用共享密鑰加密方式。

HTTPS雖好,非對(duì)稱加密雖好,但是不要濫用 HTTPS 也存在一些問題,那就是當(dāng)使用 SSL 時(shí),它的處理速度會(huì)變慢。 SSL 的慢分兩種。一種是指通信慢。另一種是指由于大量消耗 CPU 及內(nèi)存等資源,導(dǎo)致處理速度變慢。

和使用 HTTP 相比,網(wǎng)絡(luò)負(fù)載可能會(huì)變慢 2 到 100 倍。除去和 TCP 連接、發(fā)送 HTTP 請(qǐng)求 ? 響應(yīng)以外,還必須進(jìn)行 SSL 通信,因此整體上處理通信量不可避免會(huì)增加。

另一點(diǎn)是 SSL 必須進(jìn)行加密處理。在服務(wù)器和客戶端都需要進(jìn)行加密和解密的運(yùn)算處理。因此從結(jié)果上講,比起 HTTP 會(huì)更多地消耗服務(wù)器和客戶端的硬件資源,導(dǎo)致負(fù)載增強(qiáng)。

針對(duì)速度變慢這一問題,并沒有根本性的解決方案,我們會(huì)使用 SSL 加速器這種(專用服務(wù)器)硬件來改善該問題。該硬件為 SSL 通信專用硬件,相對(duì)軟件來講,能夠提高數(shù)倍 SSL 的計(jì)算速度。僅在 SSL 處理時(shí)發(fā)揮 SSL加速器的功效,以分擔(dān)負(fù)載。

為什么不一直使用 HTTPS

既然 HTTPS 那么安全可靠,那為何所有的 Web 網(wǎng)站不一直使用 HTTPS?

其中一個(gè)原因是,因?yàn)榕c純文本通信相比,加密通信會(huì)消耗更多的 CPU 及內(nèi)存資源。如果每次通信都加密,會(huì)消耗相當(dāng)多的資源,平攤到一臺(tái)計(jì)算機(jī)上時(shí),能夠處理的請(qǐng)求數(shù)量必定也會(huì)隨之減少。

因此,如果是非敏感信息則使用 HTTP 通信,只有在包含個(gè)人信息等敏感數(shù)據(jù)時(shí),才利用 HTTPS 加密通信。

特別是每當(dāng)那些訪問量較多的 Web 網(wǎng)站在進(jìn)行加密處理時(shí),它們所承擔(dān)著的負(fù)載不容小覷。在進(jìn)行加密處理時(shí),并非對(duì)所有內(nèi)容都進(jìn)行加密處理,而是僅在那些需要信息隱藏時(shí)才會(huì)加密,以節(jié)約資源。

除此之外,想要節(jié)約購(gòu)買證書的開銷也是原因之一。

要進(jìn)行 HTTPS 通信,證書是必不可少的。而使用的證書必須向認(rèn)證機(jī)構(gòu)(CA)購(gòu)買。證書價(jià)格可能會(huì)根據(jù)不同的認(rèn)證機(jī)構(gòu)略有不同。通常,一年的授權(quán)需要數(shù)萬日元(現(xiàn)在一萬日元大約折合 600 人民幣)。那些購(gòu)買證書并不合算的服務(wù)以及一些個(gè)人網(wǎng)站,可能只會(huì)選擇采用HTTP 的通信方式。

復(fù)習(xí)完了基本的協(xié)議,介紹下報(bào)文格式:

請(qǐng)求報(bào)文格式

響應(yīng)報(bào)文格式

所謂響應(yīng)頭,請(qǐng)求頭,其實(shí)都可以自己添加字段,只要前后端給對(duì)應(yīng)的處理機(jī)制即可
Node.js代碼實(shí)現(xiàn)響應(yīng)頭的設(shè)置
  if (config.cache.expires) {
                        res.setHeader("expries", new Date(Date.now() + (config.cache.maxAge * 1000)))
                    }
                    if (config.cache.lastModified) {
                        res.setHeader("last-modified", stat.mtime.toUTCString())
                    }
                    if (config.cache.etag) {
                        res.setHeader("Etag", etagFn(stat))
                    }
}
響應(yīng)頭的詳解:

本人的開源項(xiàng)目,手寫的Node.js靜態(tài)資源服務(wù)器,https://github.com/JinJieTan/...,歡迎 star~ 瀏覽器的緩存策略:

首次請(qǐng)求:

非首次請(qǐng)求:

用戶行為與緩存:

不能緩存的請(qǐng)求: 無法被瀏覽器緩存的請(qǐng)求如下:

HTTP信息頭中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告訴瀏覽器不用緩存的請(qǐng)求

需要根據(jù)Cookie,認(rèn)證信息等決定輸入內(nèi)容的動(dòng)態(tài)請(qǐng)求是不能被緩存的

經(jīng)過HTTPS安全加密的請(qǐng)求(有人也經(jīng)過測(cè)試發(fā)現(xiàn),ie其實(shí)在頭部加入Cache-Control:max-age信息,firefox在頭部加入Cache-Control:Public之后,能夠?qū)TTPS的資源進(jìn)行緩寸)

經(jīng)過HTTPS安全加密的請(qǐng)求(有人也經(jīng)過測(cè)試發(fā)現(xiàn),ie其實(shí)在頭部加入Cache-Control:max-age信息,firefox在頭部加入Cache-Control:Public之后,能夠?qū)TTPS的資源進(jìn)行緩存,參考《HTTPS的七個(gè)誤解》)

POST請(qǐng)求無法被緩存

HTTP響應(yīng)頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請(qǐng)求無法被緩存

即時(shí)通訊協(xié)議 從最初的沒有websocket協(xié)議開始:
傳統(tǒng)的協(xié)議無法服務(wù)端主動(dòng)push數(shù)據(jù),于是有了這些騷操作:

輪詢,在一個(gè)定時(shí)器中不停向服務(wù)端發(fā)送請(qǐng)求。

長(zhǎng)輪詢,發(fā)送請(qǐng)求給服務(wù)端,直到服務(wù)端覺得可以返回?cái)?shù)據(jù)了再返回響應(yīng),否則這個(gè)請(qǐng)求一直掛起~

以上兩種都有瑕疵,而且比較明顯,這里不再描述。

為了解決實(shí)時(shí)通訊,數(shù)據(jù)同步的問題,出現(xiàn)了webSocket.

webSockets的目標(biāo)是在一個(gè)多帶帶的持久連接上提供全雙工、雙向通信。在Javascript創(chuàng)建了Web Socket之后,會(huì)有一個(gè)HTTP請(qǐng)求發(fā)送到瀏覽器以發(fā)起連接。在取得服務(wù)器響應(yīng)后,建立的連接會(huì)將HTTP升級(jí)從HTTP協(xié)議交換為WebSocket協(xié)議。

webSocket原理: 在TCP連接第一次握手的時(shí)候,升級(jí)為ws協(xié)議。后面的數(shù)據(jù)交互都復(fù)用這個(gè)TCP通道。

客戶端代碼實(shí)現(xiàn):

  const ws = new WebSocket("ws://localhost:8080");
        ws.onopen = function () {
            ws.send("123")
            console.log("open")
        }
        ws.onmessage = function () {
            console.log("onmessage")
        }
        ws.onerror = function () {
            console.log("onerror")
        }
        ws.onclose = function () {
            console.log("onclose")
        }

服務(wù)端使用 Node.js語(yǔ)言實(shí)現(xiàn)

const express = require("express")
const { Server } = require("ws");
const app = express()
const wsServer = new Server({ port: 8080 })
wsServer.on("connection", (ws) => {
    ws.onopen = function () {
        console.log("open")
    }
    ws.onmessage = function (data) {
        console.log(data)
        ws.send("234")
        console.log("onmessage" + data)
    }
    ws.onerror = function () {
        console.log("onerror")
    }
    ws.onclose = function () {
        console.log("onclose")
    }
});

app.listen(8000, (err) => {
    if (!err) { console.log("監(jiān)聽OK") } else {
        console.log("監(jiān)聽失敗")
    }
})
webSocket的報(bào)文格式有一些不一樣:

![圖片上傳中...]

客戶端和服務(wù)端進(jìn)行Websocket消息傳遞是這樣的:

客戶端:將消息切割成多個(gè)幀,并發(fā)送給服務(wù)端。

服務(wù)端:接收消息幀,并將關(guān)聯(lián)的幀重新組裝成完整的消息。

即時(shí)通訊的心跳檢測(cè): pingandpong

服務(wù)端Go實(shí)現(xiàn):

package main

import (
    "net/http"
    "time"

    "github.com/gorilla/websocket"
)

var (
    //完成握手操作
    upgrade = websocket.Upgrader{
       //允許跨域(一般來講,websocket都是獨(dú)立部署的)
       CheckOrigin:func(r *http.Request) bool {
            return true
       },
    }
)

func wsHandler(w http.ResponseWriter, r *http.Request) {
   var (
         conn *websocket.Conn
         err error
         data []byte
   )
   //服務(wù)端對(duì)客戶端的http請(qǐng)求(升級(jí)為websocket協(xié)議)進(jìn)行應(yīng)答,應(yīng)答之后,協(xié)議升級(jí)為websocket,http建立連接時(shí)的tcp三次握手將保持。
   if conn, err = upgrade.Upgrade(w, r, nil); err != nil {
        return
   }

    //啟動(dòng)一個(gè)協(xié)程,每隔5s向客戶端發(fā)送一次心跳消息
    go func() {
        var (
            err error
        )
        for {
            if err = conn.WriteMessage(websocket.TextMessage, []byte("heartbeat")); err != nil {
                return
            }
            time.Sleep(5 * time.Second)
        }
    }()

   //得到websocket的長(zhǎng)鏈接之后,就可以對(duì)客戶端傳遞的數(shù)據(jù)進(jìn)行操作了
   for {
         //通過websocket長(zhǎng)鏈接讀到的數(shù)據(jù)可以是text文本數(shù)據(jù),也可以是二進(jìn)制Binary
        if _, data, err = conn.ReadMessage(); err != nil {
            goto ERR
     }
     if err = conn.WriteMessage(websocket.TextMessage, data); err != nil {
         goto ERR
     }
   }
ERR:
    //出錯(cuò)之后,關(guān)閉socket連接
    conn.Close()
}

func main() {
    http.HandleFunc("/ws", wsHandler)
    http.ListenAndServe("0.0.0.0:7777", nil)
}
客戶端的心跳檢測(cè)(Node.js實(shí)現(xiàn)):
this.heartTimer = setInterval(() => {
      if (this.heartbeatLoss < MAXLOSSTIMES) {
        events.emit("network", "sendHeart");
        this.heartbeatLoss += 1;
        this.phoneLoss += 1;
      } else {
        events.emit("network", "offline");
        this.stop();
      }
      if (this.phoneLoss > MAXLOSSTIMES) {
        this.PhoneLive = false;
        events.emit("network", "phoneDisconnect");
      }
    }, 5000);
自定義即時(shí)通信協(xié)議: new Socket開始:

目前即時(shí)通訊大都使用現(xiàn)有大公司成熟的SDK接入,但是逼格高些還是自己重寫比較好。

打個(gè)小廣告,我們公司就是自己定義的即時(shí)通訊協(xié)議~招聘一位高級(jí)前端,地點(diǎn)深圳-深南大道,做跨平臺(tái)IM桌面應(yīng)用開發(fā)的~

客戶端代碼實(shí)現(xiàn)(Node.js):

const {Socket} = require("net") 
const tcp = new Socket()
tcp.setKeepAlive(true);
tcp.setNoDelay(true);
//保持底層tcp鏈接不斷,長(zhǎng)連接
指定對(duì)應(yīng)域名端口號(hào)鏈接
tcp.connect(80,166.166.0.0)
建立連接后
根據(jù)后端傳送的數(shù)據(jù)類型 使用對(duì)應(yīng)不同的解析
readUInt8 readUInt16LE readUInt32LE readIntLE等處理后得到myBuf 
const myBuf = buffer.slice(start);//從對(duì)應(yīng)的指針開始的位置截取buffer
const header = myBuf.slice(headstart,headend)//截取對(duì)應(yīng)的頭部buffer
const body = JSON.parse(myBuf.slice(headend-headstart,bodylength).tostring())
//精確截取數(shù)據(jù)體的buffer,并且轉(zhuǎn)化成js對(duì)象
即時(shí)通訊強(qiáng)烈推薦使用Golang,GRPC,Prob傳輸數(shù)據(jù)。
上面的一些代碼,都在我的開源項(xiàng)目中:

手寫的靜態(tài)資源服務(wù)器,https://github.com/JinJieTan/...

webpack-electron-react-websocket的Demo, https://github.com/JinJieTan/...

覺得寫得不錯(cuò),可以點(diǎn)個(gè)贊支持下,文章也借鑒了一下其他大佬的文章,但是地址都貼上來了~ 歡迎gitHub點(diǎn)個(gè)star哦~

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/54276.html

相關(guān)文章

  • 什么我們熟悉這些通信協(xié)議? 【精讀

    摘要:服務(wù)器端收到報(bào)文,回應(yīng)一個(gè)報(bào)文,進(jìn)入狀態(tài)。接收到這個(gè)的對(duì)端執(zhí)行被動(dòng)關(guān)閉,這個(gè)由確認(rèn)。在連接建立后,我們可以有多種協(xié)議的方式通信交換數(shù)據(jù)最古老的方式一早先的版本,是一種無狀態(tài)無連接的應(yīng)用層協(xié)議。 打個(gè)廣告,歡迎加入我們的前端開發(fā)交流群: 微信群: showImg(https://segmentfault.com/img/bVbvM1L?w=674&h=896); QQ群 showImg(...

    svtter 評(píng)論0 收藏0
  • 什么我們熟悉這些通信協(xié)議? 【精讀

    摘要:服務(wù)器端收到報(bào)文,回應(yīng)一個(gè)報(bào)文,進(jìn)入狀態(tài)。接收到這個(gè)的對(duì)端執(zhí)行被動(dòng)關(guān)閉,這個(gè)由確認(rèn)。在連接建立后,我們可以有多種協(xié)議的方式通信交換數(shù)據(jù)最古老的方式一早先的版本,是一種無狀態(tài)無連接的應(yīng)用層協(xié)議。 打個(gè)廣告,歡迎加入我們的前端開發(fā)交流群: 微信群: showImg(https://segmentfault.com/img/bVbvM1L?w=674&h=896); QQ群 showImg(...

    smallStone 評(píng)論0 收藏0
  • 精讀《圖解HTTP》

    摘要:所以我十分建議大家去讀一下圖解和權(quán)威指南。圖解這本書對(duì)互聯(lián)網(wǎng)基盤協(xié)議進(jìn)行了全面系統(tǒng)的介紹。通過書中大量生動(dòng)形象的通信圖例,我們能夠更全面地理解通信過程中客戶端與服務(wù)器之間的交互情況。返回結(jié)果的狀態(tài)在通訊中,通過轉(zhuǎn)態(tài)碼,告知客戶端的請(qǐng)求狀態(tài)。 前言 作為一個(gè)前端,如果能夠深刻理解 HTTP 通信,能夠讓我們?cè)谌粘i_發(fā)工作中快速定位問題。所以我十分建議大家去讀一下《圖解HTTP》和《HTT...

    CrazyCodes 評(píng)論0 收藏0
  • 好文精讀 - 收藏集 - 掘金

    摘要:今天,我我的后端書架后端掘金我的后端書架月前本書架主要針對(duì)后端開發(fā)與架構(gòu)。尤其是對(duì)稱加密,非對(duì)稱加密,私鑰加密,公鑰加密滴滴動(dòng)態(tài)化方案的誕生與起航掘金這是滴滴架構(gòu)組發(fā)布的第一篇公共技術(shù)文章,本文將介紹自研的動(dòng)態(tài)化方案。 android 阿里面試題錦集 - Android - 掘金前幾天突然就經(jīng)歷了阿里android實(shí)習(xí)內(nèi)推的電面,感覺有好多以前看過的東西都忘記了,然后又復(fù)習(xí)了一下,找了...

    avwu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<