欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

WebSockets 通常用于需要即時更新的應用程序,使用 HTTP 之上的持久雙工通道來支持實時交互,而無需持續(xù)進行連接協(xié)商。服務器推送是 WebSockets 的眾多常見用例之一。

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

WebSocket 協(xié)議

以前,在瀏覽器中通過 HTTP 進行雙工通信或服務器推送需要相當多的技巧。如今,WebSockets 已成為 HTTP 的正式組成部分。它充當普通 HTTP 連接的“升級”連接。

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

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

創(chuàng)建一個簡單的服務器

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

$ npm init

接下來我們需要ws 項目,我們將使用它來支持 WebSocket:

$ npm install ws

有了這些,我們可以繪制一個簡單的回顯服務器,如下所示 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)聽端口 3000,然后監(jiān)聽WebSocket.server對象上的連接事件。一旦connection發(fā)生,我們就會獲取套接字對象 ( ws) 作為回調(diào)的參數(shù)。使用它,我們監(jiān)聽另外兩個事件:message和close。

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

請注意 ws.send() 還允許我們在需要時發(fā)送消息,因此我們可以根據(jù)其他事件將更新推送到客戶端,例如來自服務的更新或來自另一個客戶端的消息。

處理程序onClose讓我們在客戶端斷開連接時執(zhí)行工作。在本例中,我們只需記錄它即可。

測試套接字服務器

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

現(xiàn)在啟動服務器:

/websockets/server $ node echo.js

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

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

這將建立一個開放的 WebSocket 連接,讓您可以輸入到控制臺并查看響應。您將獲得如下交互:

$ 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)在,讓我們進入/websockets/client目錄并創(chuàng)建一個可用于與服務器交互的網(wǎng)頁。讓服務器在后臺運行,我們將從客戶端訪問它。

首先,創(chuàng)建一個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>

這僅提供了一個文本輸入和一個提交按鈕。它本身不做任何事情,僅提供我們在包含的腳本文件中需要的 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 設置了多個事件處理程序。腳本加載后,我們立即啟動 WebSocket,并監(jiān)視open、onclose、onmessage和onerror事件。

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

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

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

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

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

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

 當我們運行上一個命令并訪問該頁面時,我們會得到應有的表單。但是當我們在輸入框中輸入消息并點擊發(fā)送時,它顯示:

Received: [object Blob]

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

如果你查看服務器控制臺,它會顯示:

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

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

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

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

這篇快速指南闡明了 WebSocket 客戶端-服務器通信的底層機制,沒有框架的混淆。

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

當然,在許多項目中,你會希望在前端使用React之類的東西,在后端使用Node或類似的運行時。幸運的是,一旦你了解了基礎知識,這些框架就很容易集成。

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

可擴展性和錯誤處理是我們在實際 WebSockets 實現(xiàn)中需要解決的其他問題。

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

相關文章

  • NodeJS http模塊用法示例【創(chuàng)建web服務器/客戶端】

    NodeJS http模塊用法示例【創(chuàng)建web服務器/客戶端】

    這篇文章主要介紹了NodeJS http模塊用法,結(jié)合實例形式分析了node.js創(chuàng)建web服務器與客戶端,進行HTTP通信的相關操作技巧,需要的朋友可以參考下
    2019-11-11
  • Nodejs中使用phantom將html轉(zhuǎn)為pdf或圖片格式的方法

    Nodejs中使用phantom將html轉(zhuǎn)為pdf或圖片格式的方法

    這篇文章主要介紹了Nodejs中使用phantom將html轉(zhuǎn)為pdf或圖片格式的方法,需要的朋友可以參考下
    2017-09-09
  • Node.js?中的?RSA?加密、解密、簽名與驗證

    Node.js?中的?RSA?加密、解密、簽名與驗證

    RSA加密算法因其非對稱的特性,廣泛應用于數(shù)據(jù)的加密、解密、簽名和驗證等安全領域,本文主要介紹了Node.js?中的?RSA?加密、解密、簽名與驗證,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • node事件循環(huán)和process模塊實例分析

    node事件循環(huán)和process模塊實例分析

    這篇文章主要介紹了node事件循環(huán)和process模塊,結(jié)合實例形式分析了node事件循環(huán)和process模塊具體功能、使用方法及相關操作注意事項,需要的朋友可以參考下
    2020-02-02
  • 帶你了解NodeJS事件循環(huán)

    帶你了解NodeJS事件循環(huán)

    這篇文章主要介紹NodeJS事件循環(huán),Node中代碼從上到下同步執(zhí)行,在執(zhí)行過程中會將不同的任務添加到相應的隊列中,那具體有的循環(huán)又是怎么回事呢,限免現(xiàn)編就帶大家學習該詳細內(nèi)容,需要的朋友也可以參考一下
    2022-02-02
  • 快速掌握Node.js模塊封裝及使用

    快速掌握Node.js模塊封裝及使用

    這篇文章主要為大家詳細介紹了Node.js模塊封裝及使用,幫助大家快速掌握Node.js模塊封裝及使用,感興趣的小伙伴們可以參考一下
    2016-03-03
  • nodejs爬蟲抓取數(shù)據(jù)之編碼問題

    nodejs爬蟲抓取數(shù)據(jù)之編碼問題

    這篇文章主要介紹了nodejs爬蟲抓取數(shù)據(jù)之編碼問題的相關資料,需要的朋友可以參考下
    2015-07-07
  • node.js express安裝及示例網(wǎng)站搭建方法(分享)

    node.js express安裝及示例網(wǎng)站搭建方法(分享)

    下面小編就為大家?guī)硪黄猲ode.js express安裝及示例網(wǎng)站搭建方法(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 深入了解 Node的多進程服務實現(xiàn)

    深入了解 Node的多進程服務實現(xiàn)

    本文主要介紹了Node的多進程服務實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • 詳解Node.js使用token進行認證的簡單示例

    詳解Node.js使用token進行認證的簡單示例

    這篇文章主要介紹了詳解Node.js使用token進行認證的簡單示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05

最新評論