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

使用Nodejs?實現(xiàn)一個簡單的?Redis客戶端(推薦)

 更新時間:2022年11月04日 08:36:32   作者:MushRain  
在nodejs中支持TCP連接的是net模塊,?其中使用createConnection(config)或者直接new?Socket(config)來初始化一個TCP連接,這篇文章主要介紹了用Nodejs?實現(xiàn)一個簡單的?Redis客戶端,需要的朋友可以參考下

0. 寫在前面

大家如果有去看過nodejs所支持的官方庫的話,應(yīng)該會驚訝于它所提供了非常完善的網(wǎng)絡(luò)庫,不僅是應(yīng)用層,傳輸層,等等基礎(chǔ)的協(xié)議,我們可以按照事件驅(qū)動的邏輯編寫清晰易懂的網(wǎng)絡(luò)應(yīng)用,網(wǎng)絡(luò)服務(wù)。這也是本文為什么選擇Nodejs編寫的原因。

1. 背景映入

大家在使用一些數(shù)據(jù)庫軟件的時候常常會使用遠程連接

mysql -h xxx.xxx.xxx.xx -u xzzz -p

這里也指明了ip地址,但是很明顯這里可不是http協(xié)議在服務(wù),而是更加底層的協(xié)議 - 傳輸層協(xié)議,具體來說是TCP協(xié)議(Transmission Control Protocol)。通信的示意圖如下:

所以很自然的想到,數(shù)據(jù)庫的客戶端一定經(jīng)過如下流程,從而與遠程相連接:

graph TB身份驗證 --> 運輸層連接建立運輸層連接建立 --> 客戶端服務(wù)端輸入輸出綁定_通道客戶端服務(wù)端輸入輸出綁定_通道 --> 連接中斷連接中斷 --> 雙方退出釋放資源

所以我們可以嘗試向服務(wù)端發(fā)送這樣的請求消息,建立與服務(wù)端的連接,發(fā)送一些數(shù)據(jù),接受一些數(shù)據(jù),最后斷開連接。

2. 數(shù)據(jù)庫選擇

這里為了簡單起見,我們考慮不需要身份驗證的redis數(shù)據(jù)庫來作為此次實驗的服務(wù)端。
如果大家是mac,或者linux倒是可以直接安裝,如果是windows的話,推薦使用docker進行安裝,這里給出一行docker命令。

docker run  --name redis-server -p 6379:6379 -d redis:latest

3. Nodejs TCP連接

在nodejs中支持TCP連接的是net模塊, 其中使用createConnection(config)或者直接new Socket(config)來初始化一個TCP連接。
上面兩個函數(shù)不論哪一個都會返回socket實例,如果連接正常的話,就可以通過這個socket發(fā)送消息了。

當(dāng)服務(wù)端redis接收到消息之后也會返回相應(yīng)的消息,在本機客戶端通過對數(shù)據(jù)的校驗,檢查后,觸發(fā)相應(yīng)的操作(是拒絕還是接受服務(wù)端的響應(yīng))。

4. 代碼編寫

知道了原理之后,我這里直接把代碼貼出來

  • RedisSocket: 繼承自Socket
class RedisSocket extends Socket {
    constructor(config: RedisClientConfig) {
        super();
        this.connect(config.port, config.host);
    }
	// Set
    public set(key: string, value: string | number): Promise<Buffer> {
        return new Promise((resolve, reject) => {
            this.write(`SET ${key} ${value}\n`);
            const fetchAns = (chunk: Buffer) => {
                if (chunk.toString().includes("OK")) {
                    resolve(chunk);
                    this.off("data", fetchAns);
					// 在交付完成之后使用off 把函數(shù)取消綁定
                } else {
                    reject("error! can't set data");
                }
            }
            this.on("data", fetchAns);
        })
    }
	// Get
    public get(key: string): Promise<Buffer> {
        return new Promise((resolve, reject) => {
            try {
                this.write(`GET ${key}\n`);
                const fetchAns = (chunk: Buffer) => {
                    resolve(chunk);
                    this.off("data", fetchAns);
					// 在交付完成之后使用off 把函數(shù)取消綁定
                }
                this.on("data", fetchAns);
            } catch(err) {
                reject(err);
            }
        })
    }
	// 斷開TCP
    public close() {
        this.end();
    }
}

這個類將用來處理建立好后的連接的

  • RedisClient
class RedisClient {
    private config: RedisClientConfig;
    constructor(config: RedisClientConfig) {
        this.config = config; // 配置項
    }

	// 獲取redis實例
    getConnection(): Promise<RedisSocket> {
        return new Promise((resolve, reject) => {
            const socket = new RedisSocket(this.config);

            socket.on("connect", () => {
                resolve(socket);
            });

            socket.on("error", (err) => {
                reject(err);
            });
        });
    }
}

這個類用來建立與服務(wù)端的連接,使用getConnection()方法,將會交付一個redisSocket,使用這個Socket可以直接向server發(fā)送和接受數(shù)據(jù)。

5. 實驗

import { RedisClient, RedisSocket } from "./src/Client";


const Redis = new RedisClient({
    host: "localhost",
    port: 6379
});


Redis.getConnection().then((socket: RedisSocket) => {
    socket.set("Mushroom", "Cookie");
    socket.set("Mici", "Icmi").then( () => {
        socket.get("Mushroom").then((data: Buffer) => {
            console.log(data.toString());
            socket.close();
        })
    });
})

這里使用RedisClient建立與本地redis的連接,隨后通過getConnection()獲取到連接實例,并通過這個連接實例設(shè)置了兩個數(shù)據(jù),以及獲取了一數(shù)據(jù)并打印了出來。

> pnpm dev
> $6 // 這里的$6你也許會感到奇怪,不過我們很快就會知道這是什么
> Cookie

6. wireshark 抓包分析

這一次請求就是一整個完整的TCP流程,
在這其中TCP保證數(shù)據(jù)的可靠傳輸,而RESP(REdis Serialization Protocol)把數(shù)據(jù)封裝成一個fragment段,發(fā)送到下面的TCP
服務(wù)端相應(yīng)的時候也是如此,會把數(shù)據(jù)封裝起來發(fā)送到TCP中轉(zhuǎn)發(fā)出去。

看看發(fā)送方的RESP

看看響應(yīng)的RESP

所以知道了嗎?沒錯,6其實就是長度那一部分強行轉(zhuǎn)化為字符串的結(jié)果,所以在現(xiàn)在很多流行的redis客戶端中如ioredis都對RESP報文做了非常完備的解析,這使得開發(fā)者能夠非常絲滑的與redis服務(wù)端交互。(感謝這些開發(fā)者做的一切!)

7. 雜與代碼

Github 倉庫

到此這篇關(guān)于用Nodejs 實現(xiàn)一個簡單的 Redis客戶端的文章就介紹到這了,更多相關(guān)Nodejs實現(xiàn)Redis客戶端內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Node.js利用node-git-server快速搭建git服務(wù)器

    詳解Node.js利用node-git-server快速搭建git服務(wù)器

    本篇文章主要介紹了詳解Node.js利用node-git-server快速搭建git服務(wù)器,非常具有實用價值,需要的朋友可以參考下
    2017-09-09
  • Node.js+Express+Vue+MySQL+axios的項目搭建全過程

    Node.js+Express+Vue+MySQL+axios的項目搭建全過程

    這篇文章主要介紹了Node.js+Express+Vue+MySQL+axios的項目搭建全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Node.js+Express.js+TS實現(xiàn)簡單圖床腳本

    Node.js+Express.js+TS實現(xiàn)簡單圖床腳本

    在這篇博客文章中,我將介紹如何使用 TypeScript 和 Express 框架來編寫一個簡單的圖床腳本,可以將本地圖片上傳到服務(wù)器,并返回圖片的 URL,這樣,你就可以在 Markdown 文檔中方便地引用圖片,而不用擔(dān)心圖片的存儲和管理問題
    2023-10-10
  • NodeJS 實現(xiàn)多語言的示例代碼

    NodeJS 實現(xiàn)多語言的示例代碼

    這篇文章主要介紹了NodeJS 實現(xiàn)多語言的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • nodejs管理工具nvm安裝過程詳解

    nodejs管理工具nvm安裝過程詳解

    Node版本管理器--nvm,可以運行在多種操作系統(tǒng)上。nvm for windows 是使用go語言編寫的軟件。 我電腦使用的是Windows操作系統(tǒng),所以我要記錄下在此操作系統(tǒng)上nvm的安裝和使用
    2021-06-06
  • nodejs使用socket5進行代理請求的實現(xiàn)

    nodejs使用socket5進行代理請求的實現(xiàn)

    這篇文章主要介紹了nodejs使用socket5進行代理請求的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 教你用NodeJs構(gòu)建屬于自己的前端腳手工具

    教你用NodeJs構(gòu)建屬于自己的前端腳手工具

    對于腳手架我們可能天天都在接觸,像npm包管理工具,vue-cli,webpack…,但是這些腳手架是怎么做出來的,我們自己能不能做一個出來玩玩,下面這篇文章主要給大家介紹了關(guān)于如何利用NodeJs構(gòu)建屬于自己的前端腳手工具的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • node.js基于socket.io快速實現(xiàn)一個實時通訊應(yīng)用

    node.js基于socket.io快速實現(xiàn)一個實時通訊應(yīng)用

    這篇文章主要介紹了node.js基于socket.io快速實現(xiàn)一個實時通訊應(yīng)用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Node.js 回調(diào)函數(shù)實例詳解

    Node.js 回調(diào)函數(shù)實例詳解

    這篇文章主要介紹了Node.js 回調(diào)函數(shù)實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Node.js中 __dirname 的使用介紹

    Node.js中 __dirname 的使用介紹

    這篇文章主要給大家介紹了關(guān)于Node.js中 __dirname使用的相關(guān)資料,文中介紹的非常詳細,對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-06-06

最新評論