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

WebSockets帶來樂趣和利潤

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

0

79

0

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

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

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

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

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

  3. 查看基于WebSocket的應用程序的一些簡單代碼

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

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

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

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

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

請求-響應

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

  1. 您(客戶端)下達了服務員帶到廚房(服務器)的訂單(HTTP請求)。 

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

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

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

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

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

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

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

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

短輪詢

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

長時間輪詢

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

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

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

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

Web套接字

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

WebSockets在幕后

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

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

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

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

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

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

最后,當準備關閉連接時,客戶端或服務器都可以通過“關閉”消息發(fā)送。

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

一個簡短的例子

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

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

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');  });

在服務器上,我們同樣需要偵聽WebSocket請求。例如,在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的一個常見用例是發(fā)送字符串化的JSON數(shù)據(jù)甚至二進制數(shù)據(jù),從而使您能夠以方便使用的格式來構(gòu)造消息。

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

在野外

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

  • Ruby on Rails中的ActionCable,一個完整的Ruby框架 

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

  • 大猩猩Go語言

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

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

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

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

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

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

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

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

實時回顧

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

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