中文字幕一区二区人妻电影,亚洲av无码一区二区乱子伦as ,亚洲精品无码永久在线观看,亚洲成aⅴ人片久青草影院按摩,亚洲黑人巨大videos

WebSockets帶來樂趣和利潤(rùn)

發(fā)布于:2021-01-06 17:01:00

0

79

0

WebSockets 通信協(xié)議 網(wǎng)絡(luò)

在現(xiàn)代網(wǎng)絡(luò)上,無縫通信是必須的。隨著互聯(lián)網(wǎng)速度的提高,我們希望實(shí)時(shí)獲得數(shù)據(jù)。為了滿足這一需求,WebSocket是一種流行的通信協(xié)議,于2011年完成,該協(xié)議使網(wǎng)站能夠立即發(fā)送和接收數(shù)據(jù)。借助WebSocket,您可以構(gòu)建可在開放網(wǎng)絡(luò)上運(yùn)行的多人游戲,聊天應(yīng)用程序和協(xié)作軟件。 

在開始懷疑到底發(fā)生了什么之前,我用WebSockets構(gòu)建了多個(gè)項(xiàng)目。這個(gè)問題使我無所適從,很高興與您分享我所學(xué)到的知識(shí)。在本文中,我們將:

  1. 探索WebSockets解決的問題并查看替代方法

  2. 深入了解WebSockets的工作原理

  3. 查看基于WebSocket的應(yīng)用程序的一些簡(jiǎn)單代碼

  4. 通過一些實(shí)際的實(shí)現(xiàn)進(jìn)行討論

在本文的最后,您應(yīng)該輕松討論WebSockets的工作原理,甚至可能會(huì)啟發(fā)您在下一個(gè)項(xiàng)目中使用它。

互聯(lián)網(wǎng)上的消息傳遞

讓我們從基礎(chǔ)開始:WebSocket是一種允許客戶端與服務(wù)器建立雙向(“全雙工”)通信的技術(shù)。(快速回顧:客戶端是用戶計(jì)算機(jī)上的應(yīng)用程序,服務(wù)器是存儲(chǔ)網(wǎng)站和相關(guān)數(shù)據(jù)的遠(yuǎn)程計(jì)算機(jī))。

該定義中的關(guān)鍵字是雙向的:使用WebSocket,客戶端和服務(wù)器都可以觸發(fā)彼此的通信,并且兩者都可以同時(shí)發(fā)送消息。為什么這很重要?為了完全理解WebSocket的功能,讓我們退后一步,看看計(jì)算機(jī)可以從服務(wù)器獲取數(shù)據(jù)的幾種常見方式。

請(qǐng)求-響應(yīng)

在當(dāng)今大多數(shù)網(wǎng)站都使用的傳統(tǒng)HTTP系統(tǒng)中,Web服務(wù)器被設(shè)計(jì)為通過HTTP消息接收并響應(yīng)來自客戶端的請(qǐng)求。這種傳統(tǒng)的通信只能在一個(gè)方向上啟動(dòng):從客戶端到服務(wù)器。服務(wù)器代碼定義服務(wù)器應(yīng)期望的請(qǐng)求類型以及如何響應(yīng)每個(gè)請(qǐng)求。這種交流的常見隱喻是餐廳廚房。它是這樣的:

  1. 您(客戶端)下達(dá)了服務(wù)員帶到廚房(服務(wù)器)的訂單(HTTP請(qǐng)求)。 

  2. 廚房收到訂單并檢查他們是否知道如何進(jìn)行(服務(wù)器處理該請(qǐng)求)。

  3. 如果廚房知道如何做菜,他們會(huì)準(zhǔn)備訂單(服務(wù)器從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)或從服務(wù)器中獲取資產(chǎn))。

  4. 如果廚房無法識(shí)別該命令或不允許該服務(wù),則他們將壞消息發(fā)送回服務(wù)員(如果服務(wù)器不知道如何或不允許響應(yīng)該請(qǐng)求,則將其發(fā)回)錯(cuò)誤代碼,例如404)。

  5. 無論哪種方式,服務(wù)員都會(huì)返回給您(您將獲得帶有相關(guān)代碼的HTTP響應(yīng),例如200 OK或403 Forbidden)。

這里要注意的重要一點(diǎn)是,廚房不知道訂單來自誰。這種技術(shù)上的說法是“ HTTP是無狀態(tài)的”:它將每個(gè)新請(qǐng)求視為完全獨(dú)立的。我們確實(shí)有解決辦法,例如,客戶端可以發(fā)送cookie來幫助服務(wù)器識(shí)別客戶端,但是HTTP消息本身是不同的,可以獨(dú)立讀取和實(shí)現(xiàn)。

這里的問題是:廚房不能派服務(wù)員給你。當(dāng)您將服務(wù)員送去時(shí),它只會(huì)給服務(wù)員一道菜或壞消息。廚房沒有您的概念,只有您的訂單。在服務(wù)器方面,客戶端從服務(wù)器獲取更新信息的唯一方法是發(fā)送請(qǐng)求。

想象一下您正在與朋友聊天的聊天應(yīng)用程序。您將一條消息作為請(qǐng)求發(fā)送到服務(wù)器,并帶有一些文本作為有效負(fù)載。服務(wù)器收到您的請(qǐng)求并存儲(chǔ)消息。但是,它無法聯(lián)系到您朋友的計(jì)算機(jī)。您朋友的計(jì)算機(jī)還需要發(fā)送請(qǐng)求以檢查新消息;只有這樣服務(wù)器才能發(fā)送您的消息。

就目前而言,您和您的朋友(都是客戶端)都需要不斷檢查服務(wù)器的更新,從而在每條消息之間造成尷尬的延遲。太傻了吧?發(fā)送消息時(shí),您希望服務(wù)器立即對(duì)您的朋友執(zhí)行ping操作,說“嘿,您收到消息了!這里是!” 當(dāng)您需要加載靜態(tài)頁(yè)面時(shí),HTTP請(qǐng)求響應(yīng)就可以很好地工作,但是當(dāng)您的通信對(duì)時(shí)間敏感時(shí),HTTP請(qǐng)求響應(yīng)就不夠了。

短輪詢

一種解決此問題的簡(jiǎn)單方法是稱為短輪詢的技術(shù)。只需讓客戶端每隔500毫秒(或經(jīng)過一定的固定延遲)重復(fù)ping服務(wù)器。這樣,您每500ms就會(huì)獲得新數(shù)據(jù)。這有一些明顯的缺點(diǎn):存在500毫秒的延遲,它消耗大量請(qǐng)求的服務(wù)器資源,如果數(shù)據(jù)不經(jīng)常更新,大多數(shù)請(qǐng)求將返回空。

長(zhǎng)時(shí)間輪詢

延遲接收數(shù)據(jù)的另一種解決方法是一種稱為長(zhǎng)輪詢的技術(shù)。在這種方法中,服務(wù)器接收到一個(gè)請(qǐng)求,但是直到它從另一個(gè)請(qǐng)求獲取新數(shù)據(jù)后才響應(yīng)。長(zhǎng)輪詢比重復(fù)ping服務(wù)器更有效,因?yàn)樗?jié)省了解析請(qǐng)求標(biāo)頭,查詢新數(shù)據(jù)以及發(fā)送經(jīng)常為空的響應(yīng)的麻煩。但是,服務(wù)器現(xiàn)在必須跟蹤多個(gè)請(qǐng)求及其順序。同樣,請(qǐng)求可能會(huì)超時(shí),并且需要定期發(fā)出新請(qǐng)求。

服務(wù)器發(fā)送的事件(SSE)/ EventSource

另一種發(fā)送消息的技術(shù)是服務(wù)器發(fā)送事件API,它允許服務(wù)器通過利用JavaScript EventSource接口將更新推送到客戶端。EventSource使用特殊的文本/事件流標(biāo)頭通過HTTP與服務(wù)器建立持久的單向連接,并偵聽消息,這些消息在您的代碼中被視為JavaScript事件。 

這幾乎是我們所需要的—現(xiàn)在我們可以從服務(wù)器接收更新!由于服務(wù)器發(fā)送事件(SSE)是單向的,因此非常適合您不需要向服務(wù)器發(fā)送任何數(shù)據(jù)的應(yīng)用程序,例如Twitter風(fēng)格的新聞提要或股票行情的實(shí)時(shí)儀表板。另一個(gè)優(yōu)點(diǎn)是服務(wù)器發(fā)送事件可以通過HTTP進(jìn)行工作,并且該API相對(duì)易于使用。但是,舊版瀏覽器不支持SSE ,并且大多數(shù)瀏覽器都會(huì)限制您可以同時(shí)建立的SSE連接數(shù)。但是,對(duì)于我們的聊天應(yīng)用程序來說,這還不夠:接收實(shí)時(shí)更新很棒,但是我們也希望能夠發(fā)送這些更新。

Web套接字

因此,我們需要一種方法來將信息發(fā)送到服務(wù)器,并在更新進(jìn)入時(shí)從服務(wù)器接收更新。這使我們回到了前面提到的雙向(“全雙工”)通信。輸入WebSocket!幾乎所有現(xiàn)代瀏覽器都支持WebSocket API,它使我們能夠與服務(wù)器完全打開這種雙向連接。而且,服務(wù)器可以跟蹤每個(gè)客戶端并將消息推送到客戶端的子集。大!借助此功能,我們可以邀請(qǐng)我們所有的朋友加入我們的聊天應(yīng)用程序,并向其中的所有人,其中的一些人或您最好的朋友發(fā)送消息。

WebSockets在幕后

那么,這種魔術(shù)到底是如何工作的呢?不要被設(shè)置嚇倒了-像socket.io這樣的現(xiàn)代WebSocket庫(kù)抽象了很多設(shè)置,但是了解該技術(shù)的工作原理仍然很有幫助。如果在本節(jié)末尾您對(duì)更多細(xì)節(jié)感興趣,請(qǐng)查看令人驚訝的可讀性WebSocket RFC。

在上一節(jié)中,我們多次提到了HTTP。HTTP是一種協(xié)議,是計(jì)算機(jī)如何在網(wǎng)絡(luò)上通信的一組規(guī)則。它由請(qǐng)求和響應(yīng)組成,每個(gè)請(qǐng)求和響應(yīng)都包含一個(gè)請(qǐng)求行(“ GET /assets/icon.png”),標(biāo)頭和一個(gè)可選的消息主體(例如,用于POST請(qǐng)求中,用于將一些數(shù)據(jù)發(fā)送到服務(wù)器)。

WebSocket是用于發(fā)送和接收消息的另一種協(xié)議。HTTP和WebSocket都通過TCP(傳輸控制協(xié)議)連接發(fā)送消息,TCP連接是一種傳輸層標(biāo)準(zhǔn),可確保以包的形式發(fā)送的字節(jié)流可靠且可預(yù)測(cè)地從一臺(tái)計(jì)算機(jī)傳遞到另一臺(tái)計(jì)算機(jī)。因此,HTTP和WebSocket在數(shù)據(jù)包/字節(jié)級(jí)別使用相同的傳遞機(jī)制,但是用于構(gòu)造消息的協(xié)議是不同的。

為了與服務(wù)器建立WebSocket連接,客戶端首先發(fā)送帶有升級(jí)標(biāo)頭的HTTP “握手”請(qǐng)求,指定客戶端希望建立WebSocket連接。該請(qǐng)求被發(fā)送到ws:或wss :: URI(類似于http或https)。如果服務(wù)器能夠建立WebSocket連接并且允許該連接(例如,如果請(qǐng)求來自經(jīng)過身份驗(yàn)證或列入白名單的客戶端),則服務(wù)器將發(fā)送成功的握手響應(yīng),由HTTP代碼101 Switching Protocols表示。

連接升級(jí)后,協(xié)議將從HTTP切換到WebSocket,而數(shù)據(jù)包仍通過TCP發(fā)送時(shí),通信現(xiàn)在符合WebSocket消息格式。由于TCP是傳輸數(shù)據(jù)包的基礎(chǔ)協(xié)議,是全雙工協(xié)議,因此客戶端和服務(wù)器都可以同時(shí)發(fā)送消息。郵件可能是零散的,因此可以發(fā)送大型郵件而無需事先聲明大小。在這種情況下,WebSockets將其分解為多個(gè)幀。每個(gè)幀都包含一個(gè)小標(biāo)題,用于指示有效載荷的長(zhǎng)度和類型以及這是否是最后一幀。

服務(wù)器可以打開與多個(gè)客戶端的WebSocket連接,甚至可以與同一客戶端的多個(gè)連接。然后,它可以向一個(gè),一些或所有這些客戶端發(fā)送消息。實(shí)際上,這意味著多個(gè)人可以連接到我們的聊天應(yīng)用程序,并且我們可以一次向其中的一些人發(fā)送消息。

最后,當(dāng)準(zhǔn)備關(guān)閉連接時(shí),客戶端或服務(wù)器都可以通過“關(guān)閉”消息發(fā)送。

哇!接下來的工作真不錯(cuò)!讓我們休息一下,然后看一些示例代碼。

一個(gè)簡(jiǎn)短的例子

既然您已經(jīng)不再需要拉伸了(我之前不是在開玩笑?。敲醋屛覀儚募夹g(shù)概述切換到查看一些代碼。這將不那么復(fù)雜了-正如我之前提到的,現(xiàn)代工具使我們不必?fù)?dān)心握手或構(gòu)圖OpCode。

在前端,我們將使用JavaScript建立與啟用WebSockets的服務(wù)器的連接,然后將消息作為JavaScript事件進(jìn)行偵聽-就像偵聽用戶生成的事件(如單擊和按鍵)一樣。在普通JavaScript中,我們通過創(chuàng)建一個(gè)新的WebSocket對(duì)象并為open,message和close事件添加事件偵聽器來做到這一點(diǎn)。我們還使用send方法將數(shù)據(jù)發(fā)送到服務(wù)器。

const socket = new WebSocket('ws://localhost:8080'); socket.addEventListener('open', function (event) {    socket.send('Hello Server!');  });  socket.addEventListener('message', function (event) {    console.log('Message from server ', event.data); }); socket.addEventListener('close', function (event) {    console.log('The connection has been closed');  });

在服務(wù)器上,我們同樣需要偵聽WebSocket請(qǐng)求。例如,在Node.js中,我們可以使用流行的ws包打開連接并偵聽消息:

const WebSocket = require('ws'); const ws = new WebSocket.Server({ port: 8080 }); ws.on('connection', function connection(wsConnection) {   wsConnection.on('message', function incoming(message) {        console.log(`server received: ${message}`);   });   wsConnection.send('got your message!'); });

盡管在此示例中,我們正在發(fā)送字符串,但是WebSockets的一個(gè)常見用例是發(fā)送字符串化的JSON數(shù)據(jù)甚至二進(jìn)制數(shù)據(jù),從而使您能夠以方便使用的格式來構(gòu)造消息。

對(duì)于更完整的示例,Socket.io是用于建立和管理WebSocket連接的流行前端框架,它具有構(gòu)建Node / JavaScript聊天應(yīng)用程序的出色演練。該庫(kù)自動(dòng)在WebSockets和長(zhǎng)時(shí)間輪詢之間切換,并且還簡(jiǎn)化了向連接的用戶組廣播消息的過程。

在野外

盡管您可以手動(dòng)編寫WebSocket服務(wù)器代碼,但WebSockets已方便地內(nèi)置在流行的框架中。我們已經(jīng)觸及了前端的Socket.io庫(kù)。在較大的項(xiàng)目中,WebSocket的其他一些實(shí)現(xiàn)是:

  • Ruby on Rails中的ActionCable,一個(gè)完整的Ruby框架 

  • Django中的通道,全棧Python框架 

  • 大猩猩Go語言

  • Meteor,基于WebSockets而不是HTTP的全棧JavaScript框架

  • GraphQL服務(wù)器Apollo,可幫助使用WebSockets實(shí)時(shí)獲取數(shù)據(jù)

那么,哪些類型的項(xiàng)目可以從WebSockets中受益呢?任何需要實(shí)時(shí)雙向通信的項(xiàng)目都是一個(gè)很好的用例。以下是通常由WebSocket支持的幾種應(yīng)用程序:

  1. 聊天應(yīng)用程序:概念上簡(jiǎn)單的WebSockets實(shí)現(xiàn);用戶將消息發(fā)送到服務(wù)器,服務(wù)器立即將這些消息推送給收件人。不要拖延!服務(wù)器還可以在通道中存儲(chǔ)多組連接,從而允許您一次向多個(gè)人發(fā)送消息,或者在一個(gè)房間中查看來自多個(gè)人的消息,例如Slack通道。

  2. 多人游戲:多人游戲的一種常見模式是讓服務(wù)器存儲(chǔ)游戲狀態(tài)作為真相來源。玩家將執(zhí)行發(fā)送到服務(wù)器的動(dòng)作或動(dòng)作,這將更新游戲狀態(tài)并將其推出給所有玩家。使用HTTP,每個(gè)玩家都需要定期請(qǐng)求游戲狀態(tài)。使用WebSockets,每個(gè)動(dòng)作都會(huì)立即傳遞給所有玩家。

  3. 協(xié)作應(yīng)用程序:需要在共享文檔或畫布上工作嗎?您可以按照上面的模式,允許多個(gè)用戶繪制或鍵入文檔,并為所有連接的人立即更新。

  4. 開發(fā)人員工具: CircleCI等持續(xù)集成工具使用WebSockets在構(gòu)建完成后立即通知您。是否需要發(fā)送有關(guān)網(wǎng)站性能和訪問者數(shù)量的客戶指標(biāo)?打開WebSocket連接,并在服務(wù)器收到更新后立即發(fā)送更新。

  5. 位置相關(guān)的應(yīng)用程序:當(dāng)用戶的GPS坐標(biāo)已更改時(shí),更新服務(wù)器,然后根據(jù)其當(dāng)前坐標(biāo)向用戶發(fā)送新數(shù)據(jù)。

實(shí)時(shí)回顧

希望到目前為止,您已經(jīng)在WebSockets上出售了!我們有很多基礎(chǔ)知識(shí):我們追蹤了WebSockets解決的問題和替代解決方案,探討了WebSockets如何在后臺(tái)運(yùn)行,甚至研究了一些示例代碼和常見用例。 

WebSocket協(xié)議是構(gòu)建實(shí)時(shí)通信應(yīng)用程序的絕佳工具,但與所有工具一樣,它不是靈丹妙藥。WebSocket連接本來是持久的,所以對(duì)于簡(jiǎn)單的應(yīng)用程序來說可能會(huì)過大。對(duì)于單向新聞提要,指標(biāo)提要或您需要更新客戶端但又不會(huì)收到信息的任何應(yīng)用程序,“服務(wù)器發(fā)送事件”或普通的舊HTTP調(diào)用設(shè)置起來更快捷,更簡(jiǎn)單。但是,對(duì)于多人游戲和協(xié)作應(yīng)用程序,WebSockets開辟了無限的可能性。實(shí)時(shí)網(wǎng)絡(luò)正在發(fā)展,WebSocket協(xié)議是其發(fā)展的關(guān)鍵要素。繼續(xù)使用并永久使用它!