最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js中的WebSocket底層實(shí)現(xiàn)

 更新時(shí)間:2024年10月14日 08:30:31   作者:網(wǎng)絡(luò)研究觀  
WebSockets是基于HTTP的雙向通信協(xié)議,允許客戶端和服務(wù)器之間實(shí)現(xiàn)實(shí)時(shí)、持久的數(shù)據(jù)交換,本文詳細(xì)介紹了使用JavaScript和Node.js創(chuàng)建WebSockets服務(wù)器和客戶端的過(guò)程,感興趣的可以了解一下

WebSockets 是一種網(wǎng)絡(luò)通信協(xié)議,可實(shí)現(xiàn)雙向客戶端-服務(wù)器通信。

WebSockets 通常用于需要即時(shí)更新的應(yīng)用程序,使用 HTTP 之上的持久雙工通道來(lái)支持實(shí)時(shí)交互,而無(wú)需持續(xù)進(jìn)行連接協(xié)商。服務(wù)器推送是 WebSockets 的眾多常見(jiàn)用例之一。

本文首先從代碼角度研究了 JavaScript 中 WebSockets 方程的兩邊,在服務(wù)器上使用 Node.js,在瀏覽器中使用原始 JavaScript。

WebSocket 協(xié)議

以前,在瀏覽器中通過(guò) HTTP 進(jìn)行雙工通信或服務(wù)器推送需要相當(dāng)多的技巧。如今,WebSockets 已成為 HTTP 的正式組成部分。它充當(dāng)普通 HTTP 連接的“升級(jí)”連接。

WebSockets 可讓您在瀏覽器客戶端和后端之間來(lái)回發(fā)送任意數(shù)據(jù)。任一端都可以發(fā)起新消息,因此您擁有了用于各種需要持續(xù)通信或廣播的實(shí)時(shí)應(yīng)用程序的基礎(chǔ)架構(gòu)。開(kāi)發(fā)人員將 WebSockets 協(xié)議用于游戲、聊天應(yīng)用程序、直播、協(xié)作應(yīng)用程序等??赡苄詿o(wú)窮無(wú)盡。

為了本文的目的,我們將創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器和客戶端,然后使用它們來(lái)深入了解 WebSockets 通信期間發(fā)生的情況。

創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器

首先,您需要一個(gè)/server包含兩個(gè)子目錄的目錄/client和/server。有了這些之后,您需要一個(gè)非常簡(jiǎn)單的 Node 服務(wù)器,該服務(wù)器建立 WebSocket 連接并回顯發(fā)送給它的任何內(nèi)容。接下來(lái),進(jìn)入/websockets/server并開(kāi)始一個(gè)新項(xiàng)目:

$ npm init

接下來(lái)我們需要ws 項(xiàng)目,我們將使用它來(lái)支持 WebSocket:

$ npm install ws

有了這些,我們可以繪制一個(gè)簡(jiǎn)單的回顯服務(wù)器,如下所示 echo.js:

// echo.js
const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 3000 });

wss.on('connection', (ws) => {
  console.log('Client connected');

  ws.on('message', (message) => {
    console.log('Received message:', message);   

    ws.send(message); // Echo the message back to the client
  });

  ws.on('close', () => {
    console.log('Client disconnected');
  });
});

console.log(‘server started');

這里,我們監(jiān)聽(tīng)端口 3000,然后監(jiān)聽(tīng)WebSocket.server對(duì)象上的連接事件。一旦connection發(fā)生,我們就會(huì)獲取套接字對(duì)象 ( ws) 作為回調(diào)的參數(shù)。使用它,我們監(jiān)聽(tīng)另外兩個(gè)事件:message和close。

每當(dāng)客戶端發(fā)送消息時(shí),它都會(huì)調(diào)用onMessage處理程序并將消息傳遞給我們。在該處理程序中,我們使用ws.send()方法發(fā)送回顯響應(yīng)。

請(qǐng)注意 ws.send() 還允許我們?cè)谛枰獣r(shí)發(fā)送消息,因此我們可以根據(jù)其他事件將更新推送到客戶端,例如來(lái)自服務(wù)的更新或來(lái)自另一個(gè)客戶端的消息。

處理程序onClose讓我們?cè)诳蛻舳藬嚅_(kāi)連接時(shí)執(zhí)行工作。在本例中,我們只需記錄它即可。

測(cè)試套接字服務(wù)器

如果能有一種簡(jiǎn)單的方法從命令行測(cè)試套接字服務(wù)器就好了,Websocat 工具非常適合此目的。它的安裝過(guò)程很簡(jiǎn)單,如這里所述,并且有許多使用它的示例。

現(xiàn)在啟動(dòng)服務(wù)器:

/websockets/server $ node echo.js

使用Ctrl-z和將其置于背景狀態(tài)$ bg,然后運(yùn)行以下命令:

$ ./websocat.x86_64-unknown-linux-musl -t --ws-c-uri=wss://localhost:3000/ - ws-c:cmd:'socat - ssl:echo.websocket.org:443,verify=0'

這將建立一個(gè)開(kāi)放的 WebSocket 連接,讓您可以輸入到控制臺(tái)并查看響應(yīng)。您將獲得如下交互:

$ node echo.js 
Server started
^Z
[1]+  Stopped                 node echo.js
matthewcarltyson@dev3:~/websockets/server$ bg
[1]+ node echo.js &
matthewcarltyson@dev3:~/websockets/server$ ./websocat.x86_64-unknown-linux-musl -t --ws-c-uri=wss://localhost:3000/ - ws-c:cmd:'socat - ssl:echo.websocket.org:443,verify=0'
Request served by 7811941c69e658
An echo test
An echo test
Works
Works
^C
matthewcarltyson@dev3:~/websockets/server$ fg
node echo.js
^C

創(chuàng)建客戶端

現(xiàn)在,讓我們進(jìn)入/websockets/client目錄并創(chuàng)建一個(gè)可用于與服務(wù)器交互的網(wǎng)頁(yè)。讓服務(wù)器在后臺(tái)運(yùn)行,我們將從客戶端訪問(wèn)它。

首先,創(chuàng)建一個(gè)index.html如下文件:

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket Client</title>
</head>
<body>
    <h1>WebSocket Client</h1>
    <input type="text" id="message" placeholder="Enter message">
    <button id="send-btn">Send</button>
    <div id="output"></div>
    <script src="script.js"></script>
</body>
</html>

這僅提供了一個(gè)文本輸入和一個(gè)提交按鈕。它本身不做任何事情,僅提供我們?cè)诎哪_本文件中需要的 DOM 元素:

// script.js
const wsUri = "ws://localhost:3000";
const outputDiv = document.getElementById("output");
const messageInput = document.getElementById("message");
const sendButton = document.getElementById("send-btn");

let websocket;

function connect() {
    websocket = new WebSocket(wsUri);

    websocket.onopen = function (event) {
        outputDiv.innerHTML += "
Connected to server!

";
    };

    websocket.onmessage = function (event) {
        const receivedMessage = event.data;
        outputDiv.innerHTML += "
Received: " + receivedMessage + "

";
    };

    websocket.onerror = function (event) {
        outputDiv.innerHTML += "
Error: " + event.error + "

";
    };

    websocket.onclose = function (event) {
        outputDiv.innerHTML += "
Connection closed.

";
    };
}

sendButton.addEventListener("click", function () {
    const message = messageInput.value;
    if (websocket && websocket.readyState === WebSocket.OPEN) {
        websocket.send(message);
        messageInput.value = "";
    } else {
        outputDiv.innerHTML += "
Error: Connection not open.

";
    }
});

connect(); // Connect immediately

此腳本使用瀏覽器原生 API 設(shè)置了多個(gè)事件處理程序。腳本加載后,我們立即啟動(dòng) WebSocket,并監(jiān)視open、onclose、onmessage和onerror事件。

每個(gè)事件都會(huì)將其更新附加到 DOM。最重要的是onmessage,我們從服務(wù)器接受消息并顯示它。

按鈕本身的 Click 處理程序接收用戶輸入的輸入(messageInput.value),并使用 WebSocket 對(duì)象通過(guò)函數(shù)將其發(fā)送到服務(wù)器send()。然后我們將輸入的值重置為空字符串。

假設(shè)后端仍在運(yùn)行且可在ws://localhost:3000處使用,我們現(xiàn)在可以運(yùn)行前端。我們可以使用http-server作為運(yùn)行前端的簡(jiǎn)單方法。

這是一種在 Web 服務(wù)器中托管靜態(tài)文件的簡(jiǎn)單方法,類似于 Python 的 http 模塊或Java 的簡(jiǎn)單 Web 服務(wù)器,但適用于 Node。

它可以作為全局 NPM 包安裝,也可以簡(jiǎn)單地npx從客戶端目錄使用運(yùn)行:

/websockets/client/ $ npx http-server -o

 當(dāng)我們運(yùn)行上一個(gè)命令并訪問(wèn)該頁(yè)面時(shí),我們會(huì)得到應(yīng)有的表單。但是當(dāng)我們?cè)谳斎肟蛑休斎胂⒉Ⅻc(diǎn)擊發(fā)送時(shí),它顯示:

Received: [object Blob]

ws如果您查看瀏覽器開(kāi)發(fā)控制臺(tái),所有內(nèi)容都通過(guò) WebSocket 通道(選項(xiàng)卡中的選項(xiàng)卡)進(jìn)行network。問(wèn)題是,為什么它會(huì)以 blob 的形式返回?

如果你查看服務(wù)器控制臺(tái),它會(huì)顯示:

Client connected
Received message: <Buffer 6f 6d 20 6d 61 6e 69 20 70 61 64 6d 65 20 68 75 6d>

所以現(xiàn)在我們知道問(wèn)題出在服務(wù)器上。問(wèn)題是ws模塊的較新版本不會(huì)自動(dòng)將消息解碼為字符串,而是只提供二進(jìn)制緩沖區(qū)。這是echo.js onmessage處理程序中的快速修復(fù): 

ws.on('message', (message, isBinary) => {
  message = isBinary ? message : message.toString();
  console.log('Received message:', message);   
  ws.send(message); 
});

我們對(duì)回調(diào)使用第二個(gè)參數(shù)isBinary,如果處理程序接收到一個(gè)字符串,我們會(huì)使用快速將其轉(zhuǎn)換為字符串message.toString()。

這篇快速指南闡明了 WebSocket 客戶端-服務(wù)器通信的底層機(jī)制,沒(méi)有框架的混淆。

如您所見(jiàn),使用 WebSocket 高級(jí)功能的基礎(chǔ)非常簡(jiǎn)單。只需使用簡(jiǎn)單的回調(diào)和消息發(fā)送,您就可以使用瀏覽器標(biāo)準(zhǔn) API 和流行的 Node 庫(kù)進(jìn)行全雙工和異步通信。

當(dāng)然,在許多項(xiàng)目中,你會(huì)希望在前端使用React之類的東西,在后端使用Node或類似的運(yùn)行時(shí)。幸運(yùn)的是,一旦你了解了基礎(chǔ)知識(shí),這些框架就很容易集成。

此處的討論和示例有意忽略了安全性,就像 Web 開(kāi)發(fā)的每個(gè)領(lǐng)域一樣,安全性增加了一層復(fù)雜性,需要在堆棧的兩側(cè)進(jìn)行管理。

可擴(kuò)展性和錯(cuò)誤處理是我們?cè)趯?shí)際 WebSockets 實(shí)現(xiàn)中需要解決的其他問(wèn)題。

到此這篇關(guān)于Node.js中的WebSocket底層實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Node.js WebSocket底層內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解Node.js中通用基礎(chǔ)設(shè)計(jì)模式

    深入理解Node.js中通用基礎(chǔ)設(shè)計(jì)模式

    大家在談到設(shè)計(jì)模式時(shí)最先想到的就是 singletons, observers(觀察者) 或 factories(工廠方法)。本文重點(diǎn)給大家介紹Node.JS一些基礎(chǔ)模式的實(shí)現(xiàn)方法,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2017-09-09
  • Node.js Buffer模塊功能及常用方法實(shí)例分析

    Node.js Buffer模塊功能及常用方法實(shí)例分析

    這篇文章主要介紹了Node.js Buffer模塊功能及常用方法,結(jié)合實(shí)例形式分析了Buffer模塊的各種常用函數(shù)及相關(guān)使用技巧,需要的朋友可以參考下
    2019-01-01
  • 使用npm安裝最新版本nodejs

    使用npm安裝最新版本nodejs

    本文給大家分享的是如何使用npm安裝最新版本nodejs的方法,主要用到了nodejs版本管理模塊n,非常的好用,有需要的小伙伴可以參考下
    2018-01-01
  • 解決npm install命令一直失敗的坑

    解決npm install命令一直失敗的坑

    文章總結(jié):執(zhí)行npminstall命令失敗,可能是由于代理問(wèn)題,可以嘗試更換代理、權(quán)限、VSCode版本或網(wǎng)絡(luò)環(huán)境(如使用移動(dòng)熱點(diǎn))來(lái)解決
    2024-12-12
  • npm下載慢或下載失敗問(wèn)題解決的三種方法

    npm下載慢或下載失敗問(wèn)題解決的三種方法

    這篇文章主要為大家介紹了npm下載慢或下載失敗問(wèn)題解決的三種方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • node跨域轉(zhuǎn)發(fā) express+http-proxy-middleware的使用

    node跨域轉(zhuǎn)發(fā) express+http-proxy-middleware的使用

    這篇文章主要介紹了node跨域轉(zhuǎn)發(fā) express+http-proxy-middleware的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 詳解在Node.js中發(fā)起HTTP請(qǐng)求的5種方法

    詳解在Node.js中發(fā)起HTTP請(qǐng)求的5種方法

    這篇文章主要介紹了詳解在Node.js中發(fā)起HTTP請(qǐng)求的5種方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • node.js中的fs.chmodSync方法使用說(shuō)明

    node.js中的fs.chmodSync方法使用說(shuō)明

    這篇文章主要介紹了node.js中的fs.chmodSync方法使用說(shuō)明,本文介紹了fs.chmodSync方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • pm2工具在Node.js開(kāi)發(fā)部署中的重要作用詳解

    pm2工具在Node.js開(kāi)發(fā)部署中的重要作用詳解

    這篇文章主要為大家介紹了pm2工具在Node.js開(kāi)發(fā)部署中的重要作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • npm?list輸出結(jié)果包含extraneous標(biāo)志記錄分析

    npm?list輸出結(jié)果包含extraneous標(biāo)志記錄分析

    這篇文章主要為大家介紹了npm?list輸出結(jié)果包含extraneous標(biāo)志記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01

最新評(píng)論

黑水县| 额尔古纳市| 巴马| 静海县| 长乐市| 班戈县| 尚义县| 通河县| 农安县| 安国市| 扎兰屯市| 南平市| 乐清市| 巨鹿县| 宁德市| 铅山县| 舞钢市| 宁武县| 门源| 玛纳斯县| 梅河口市| 承德市| 廉江市| 桦甸市| 昭平县| 法库县| 千阳县| 抚远县| 苍梧县| 武功县| 东乌珠穆沁旗| 五台县| 周口市| 南郑县| 郯城县| 冕宁县| 文化| 呼伦贝尔市| 隆子县| 静乐县| 藁城市|