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

使用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ù)庫軟件的時候常常會使用遠(yuǎn)程連接

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

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

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

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

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

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

這里為了簡單起見,我們考慮不需要身份驗證的redis數(shù)據(jù)庫來作為此次實驗的服務(wù)端。
如果大家是mac,或者linux倒是可以直接安裝,如果是windows的話,推薦使用docker進(jìn)行安裝,這里給出一行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)的消息,在本機(jī)客戶端通過對數(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其實就是長度那一部分強(qiáng)行轉(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中的fs.statSync方法使用說明

    node.js中的fs.statSync方法使用說明

    這篇文章主要介紹了node.js中的fs.statSync方法使用說明,本文介紹了fs.statSync的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Node中的streams流的具體使用

    Node中的streams流的具體使用

    本文主要介紹了Node中的streams流的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Ajax獲取node服務(wù)器數(shù)據(jù)的完整步驟

    Ajax獲取node服務(wù)器數(shù)據(jù)的完整步驟

    這篇文章主要給大家介紹了關(guān)于Ajax獲取node服務(wù)器數(shù)據(jù)的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • express框架下使用session的方法

    express框架下使用session的方法

    這篇文章主要介紹了express框架下使用session的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 在Node.js中設(shè)置響應(yīng)的MIME類型的代碼詳解

    在Node.js中設(shè)置響應(yīng)的MIME類型的代碼詳解

    在 Node.js 中設(shè)置響應(yīng)的 MIME 類型是為了讓瀏覽器正確解析服務(wù)器返回的內(nèi)容,比如 HTML、CSS、圖片、JSON 等,我們通常通過設(shè)置響應(yīng)頭中的 Content-Type 字段來完成,本文就給大家詳細(xì)介紹了在Node.js中設(shè)置響應(yīng)的MIME類型的方法,需要的朋友可以參考下
    2025-04-04
  • NodeJS實現(xiàn)自定義流的方法

    NodeJS實現(xiàn)自定義流的方法

    在 NodeJS 中要想實現(xiàn)自定義流,需要依賴模塊 stream ,直接引入,不需下載,所有種類的流都是繼承這個模塊內(nèi)部提供的對應(yīng)不同種類的類來實現(xiàn)的。接下來通過本文給大家介紹NodeJS實現(xiàn)自定義流的方法,一起看看吧
    2018-08-08
  • Node.js中npm 和 peerDependencies的使用

    Node.js中npm 和 peerDependencies的使用

    本文詳細(xì)介紹了npm中的peerDependencies和--legacy-peer-deps使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • Node.js?搭建后端服務(wù)器內(nèi)置模塊(?http+url+querystring?的使用)

    Node.js?搭建后端服務(wù)器內(nèi)置模塊(?http+url+querystring?的使用)

    這篇文章主要介紹了Node.js搭建后端服務(wù)器內(nèi)置模塊(http+url+querystring的使用),文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價值,需要的朋友可以參考一下
    2022-09-09
  • NodeJS學(xué)習(xí)筆記之(Url,QueryString,Path)模塊

    NodeJS學(xué)習(xí)筆記之(Url,QueryString,Path)模塊

    今天我們來看一下在nodejs中路徑的相關(guān)操作方法。在我們開發(fā)過程中路徑主要有:URL路徑,在瀏覽器中進(jìn)行使用,當(dāng)然這個也包含查詢字符串QueryString的相關(guān)操作;而另一種是磁盤路徑,主要用于文件等等進(jìn)行操作,我們稱為Path,所以我將它們放在一起進(jìn)行總結(jié)學(xué)習(xí)。
    2015-01-01
  • 關(guān)于Node.js中頻繁修改代碼重啟服務(wù)器的問題

    關(guān)于Node.js中頻繁修改代碼重啟服務(wù)器的問題

    這篇文章主要介紹了關(guān)于Node.js中頻繁修改代碼重啟服務(wù)器的問題,本文給大家分享解決辦法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10

最新評論

逊克县| 三河市| 乌鲁木齐县| 满洲里市| 公主岭市| 甘德县| 黄冈市| 翁牛特旗| 红河县| 通榆县| 巴彦淖尔市| 邯郸市| 济源市| 汽车| 昭觉县| 天祝| 如东县| 罗山县| 宝鸡市| 门头沟区| 金溪县| 老河口市| 肃北| 葫芦岛市| 巴东县| 治县。| 文昌市| 盐源县| 巍山| 白山市| 安泽县| 晋城| 浦东新区| 鄱阳县| 景德镇市| 西平县| 安溪县| 宝山区| 永清县| 剑河县| 神农架林区|