使用Nodejs 实现一个简单的 Redis客户端(推荐)

 更新时间:2022年11月04日 08:36:32   作者:MushRain  
在nodejs中支持TCP连接的是net模块, 其中使用createConnection(config)或者直接new Socket(config)来初始化一个TCP连接,这篇文章主要介绍了用Nodejs 实现一个简单的 Redis客户端,需要的朋友可以参考下

0. 写在前面

大家如果有去看过nodejs所支持的官方库的话,应该会惊讶于它所提供了非常完善的网络库,不仅是应用层,传输层,等等基础的协议,我们可以按照事件驱动的逻辑编写清晰易懂的网络应用,网络服务。这也是本文为什么选择Nodejs编写的原因。

1. 背景映入

大家在使用一些数据库软件的时候常常会使用远程连接

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

这里也指明了ip地址,但是很明显这里可不是http协议在服务,而是更加底层的协议 - 传输层协议,具体来说是TCP协议(Transmission Control Protocol)。通信的示意图如下:

所以很自然的想到,数据库的客户端一定经过如下流程,从而与远程相连接:

graph TB身份验证 --> 运输层连接建立运输层连接建立 --> 客户端服务端输入输出绑定_通道客户端服务端输入输出绑定_通道 --> 连接中断连接中断 --> 双方退出释放资源

所以我们可以尝试向服务端发送这样的请求消息,建立与服务端的连接,发送一些数据,接受一些数据,最后断开连接。

2. 数据库选择

这里为了简单起见,我们考虑不需要身份验证的redis数据库来作为此次实验的服务端。
如果大家是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连接。
上面两个函数不论哪一个都会返回socket实例,如果连接正常的话,就可以通过这个socket发送消息了。

当服务端redis接收到消息之后也会返回相应的消息,在本机客户端通过对数据的校验,检查后,触发相应的操作(是拒绝还是接受服务端的响应)。

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 把函数取消绑定
                } 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 把函数取消绑定
                }
                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);
            });
        });
    }
}

这个类用来建立与服务端的连接,使用getConnection()方法,将会交付一个redisSocket,使用这个Socket可以直接向server发送和接受数据。

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()获取到连接实例,并通过这个连接实例设置了两个数据,以及获取了一数据并打印了出来。

> pnpm dev
> $6 // 这里的$6你也许会感到奇怪,不过我们很快就会知道这是什么
> Cookie

6. wireshark 抓包分析

这一次请求就是一整个完整的TCP流程,
在这其中TCP保证数据的可靠传输,而RESP(REdis Serialization Protocol)把数据封装成一个fragment段,发送到下面的TCP
服务端相应的时候也是如此,会把数据封装起来发送到TCP中转发出去。

看看发送方的RESP

看看响应的RESP

所以知道了吗?没错,6其实就是长度那一部分强行转化为字符串的结果,所以在现在很多流行的redis客户端中如ioredis都对RESP报文做了非常完备的解析,这使得开发者能够非常丝滑的与redis服务端交互。(感谢这些开发者做的一切!)

7. 杂与代码

Github 仓库

到此这篇关于用Nodejs 实现一个简单的 Redis客户端的文章就介绍到这了,更多相关Nodejs实现Redis客户端内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • NodeJs读取JSON文件格式化时的注意事项

    NodeJs读取JSON文件格式化时的注意事项

    本文是作者在进行NodeJs开发时偶然发现的问题,经过一番努力,最终找到解决方案,分享给大家,有需要的小伙伴可以参考下
    2016-09-09
  • yarn安装路径的成功修改并配置环境

    yarn安装路径的成功修改并配置环境

    Yarn是facebook发布的一款取代npm的包管理工具,下面这篇文章主要给大家介绍了关于yarn安装路径的成功修改并配置环境的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • node.js中的console.error方法使用说明

    node.js中的console.error方法使用说明

    这篇文章主要介绍了node.js中的console.error方法使用说明,本文介绍了console.error的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12
  • 使用node.js 制作网站前台后台

    使用node.js 制作网站前台后台

    本文给大家介绍实用node.js 制作网站前台和后台,非常的详尽,有需要的朋友可以参考下
    2014-11-11
  • Node.js dgram模块实现UDP通信示例代码

    Node.js dgram模块实现UDP通信示例代码

    这篇文章主要介绍了Node.js dgram模块实现UDP通信示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • node+express+axios实现单文件上传功能

    node+express+axios实现单文件上传功能

    这篇文章主要为大家详细介绍了node+express+axios实现单文件上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • React和Node.js快速上传进度条功能实现

    React和Node.js快速上传进度条功能实现

    这篇文章主要为大家介绍了React和Node.js快速上传进度条功能实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • node.js如何充分利用多核cpu

    node.js如何充分利用多核cpu

    这篇文章主要介绍了node.js如何充分利用多核cpu,想了解node.js的同学,可以参考下
    2021-04-04
  • 修改Nodejs内置的npm默认配置路径方法

    修改Nodejs内置的npm默认配置路径方法

    今天小编就为大家分享一篇修改Nodejs内置的npm默认配置路径方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • node省市区三级数据性能测评实例分析

    node省市区三级数据性能测评实例分析

    这篇文章主要介绍了node省市区三级数据性能,结合具体实例形式评测分析了node省市区三级数据的实现、改进方法与运行效率,需要的朋友可以参考下
    2019-11-11

最新评论