redis协议格式请参考,http://doc.redisfans.com/topic/protocol.html

这里简单介绍下:

*<参数数量> \r\n
$<参数 的字节数量> \r\n
<参数 的数据> \r\n
$<参数 N 的字节数量> \r\n
<参数 N 的数据> \r\n

发送给redis服务器时的数据要按照redis要求的协议格式发送,只有这样redis服务器才能成功解析。

首先根据协议格式写一个封包方法,代码如下:

    def format_command(self, commands):
length = len(commands)
command = "*{}\r\n".format(length)
for v in commands:
bytes = v.encode("utf-8")
bytes_length = len(bytes)
sub_command = "${}\r\n".format(bytes_length) + "{}\r\n".format(v)
command += sub_command
return command

看到format_command函数中的“*”和“$”符号了么。其实就是根据commands列表中的数据然后按照redis协议格式封装起来的。

弄懂了如何安装redis协议封装数据之后,就可以把数据发送到redis服务器了。

asyncio的官方demo可参考:

https://docs.python.org/3/library/asyncio-stream.html#tcp-echo-client-using-streams

下面就是完整的代码,无其他依赖,顺利执行之后,可以通过redis-cli命令行查看是否设置成功。


class AsyncRedis:

    def __init__(self, host, port, loop):
self.host = host
self.port = port
self.loop = loop
self.separator = "\r\n".encode() async def connect(self):
reader, writer = await asyncio.open_connection(self.host, self.port, loop=self.loop)
self.reader = reader
self.writer = writer def format_command(self, commands):
length = len(commands)
command = "*{}\r\n".format(length)
for v in commands:
bytes = v.encode("utf-8")
bytes_length = len(bytes)
sub_command = "${}\r\n".format(bytes_length) + "{}\r\n".format(v)
command += sub_command
print(command)
return command def execute_command(self, command):
self.writer.write(command.encode("utf-8")) async def set(self, key, value):
command = self.format_command(["SET", key, value])
self.execute_command(command)
ret, error = await self.wait_ret()
print(ret)
return ret async def hset(self, hash_key, key, value):
command = self.format_command(["HSET", hash_key, key, value])
self.execute_command(command) async def get(self, key):
command = self.format_command(['GET', key])
self.execute_command(command)
ret = await self.wait_ret()
return ret async def wait_ret(self):
ret = await self.reader.readuntil(self.separator)
ret = ret.decode()
mark = ret[0:1]
if mark == "$":
pos = ret.index("\r\n")
ret = ret[1:pos]
ret = await self.reader.read(int(ret))
ret = ret.decode()
return ret, True
elif mark == "+":
pos = ret.index("\r\n")
ret = ret[1:pos]
return ret, True
elif mark == "-":
pos = ret.index("\r\n")
ret = ret[1:pos]
return ret, False async def close(self):
self.writer.close() import asyncio async def NewRedis(loop):
redis = AsyncRedis("127.0.0.1", 6379, loop)
await redis.connect()
# await redis.get("name")
await redis.set("name", "云想衣裳花想容,春风拂槛露华浓。\r\n 若非群玉山头见,会向瑶台月下逢。")
loop = asyncio.get_event_loop()
loop.run_until_complete(NewRedis(loop))
loop.close()

使用asyncio实现redis客户端的更多相关文章

  1. 测试平台系列(80) 封装Redis客户端

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们编写了Redis ...

  2. StackExchange.Redis客户端读写主从配置,以及哨兵配置。

    今天简单分享一下StackExchange.Redis客户端中配置主从分离以及哨兵的配置. 关于哨兵如果有不了解的朋友,可以看我之前的一篇分享,当然主从复制文章也可以找到.http://www.cnb ...

  3. c#实现redis客户端(一)

    最近项目使用中要改造redis客户端,看了下文档,总结分享一下. 阅读目录: 协议规范 基础通信 状态命令 set.get命令 管道.事务 总结 协议规范 redis允许客户端以TCP方式连接,默认6 ...

  4. 使用StackExchange.Redis客户端进行Redis访问出现的Timeout异常排查

    问题产生 这两天业务系统在redis的使用过程中,当并行客户端数量达到200+之后,产生了大量timeout异常,典型的异常信息如下: Timeout performing HVALS Parser2 ...

  5. Redis客户端之Spring整合Jedis,ShardedJedisPool集群配置

    Jedis设计 Jedis作为推荐的java语言redis客户端,其抽象封装为三部分: 对象池设计:Pool,JedisPool,GenericObjectPool,BasePoolableObjec ...

  6. 从零开始写redis客户端(deerlet-redis-client)之路——第一个纠结很久的问题,restore引发的血案

    引言 正如之前的一篇博文,LZ最近正在从零开始写一个redis的客户端,主要目的是为了更加深入的了解redis,当然了,LZ也希望deerlet客户端有一天能有一席之地.在写的过程当中,LZ遇到了一个 ...

  7. Redis 客户端配置及示例

    一.redis自定义配置节点 <configSections> <section name ="RedisConfig" type="Amy.Toolk ...

  8. Redis客户端Java服务接口封装

    最近在学习Redis并集成到Spring中去,发现Spring的RedisTemplate并不好用,还没有MongoTemplate好用. 而且发现Jedis和ShardedJedis的方法非常多,覆 ...

  9. "Redis客户端连接数一直降不下来"的有关问题解决

    [线上问题] "Redis客户端连接数一直降不下来"的问题解决 前段时间,上线了新的 Redis缓存(Cache)服务,准备替换掉 Memcached. 为什么要将 Memcach ...

随机推荐

  1. 洛谷 P2073 送花【Treap】题解+AC代码

    题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地向里面 ...

  2. LaTeX 各种命令,符号

    函数.符号及特殊字符 声调 语法 效果 语法 效果 语法 效果 \bar{x} \acute{\eta} \check{\alpha} \grave{\eta} \breve{a} \ddot{y} ...

  3. 利用mock提高效率

    利用mock提高效率 谈到mock,就不得不讲前后端分离.理想情况下前后端不分离,由全栈的人以product和infrastructure的维度进行开发,效率是最高的.近些年来业务的复杂度越来越高,真 ...

  4. Yii小部件

    小部件 Yii提供了一套数据小部件widgets,这些小部件可以用于显示数据. DetailView小部件用于显示一条记录数据. ListView和GridView小部件能够用于显示一个拥有分页.排序 ...

  5. 关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思

    关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思 一.遇到的问题      如题目所说,在windows的虚拟机中和windo ...

  6. 使用commons-csv简单读写CSV文件

    文章首发于我的github博客 需求 客户的开发测试环境将做迁移.因此需要对zookeeper上的重要的数据以CSV文件格式做备份. 本文通过Apache的commons-csv操作CSV文件.官网地 ...

  7. PAT1119. Pre- and Post-order Traversals

    思路:中序遍历–根结点,左子树,右子树:后序遍历–左子树,右子树,根结点. 那么在找到根结点之后就可以开始划分左右子树了.左子树的先序第一个节点是根,左子树的后序最后一个节点是根. 例如 1 2 3 ...

  8. uva1343 IDA*

    这题需要用数组记录每个block的位置.启发函数:d+wa(8-当前最多相同个数)>maxd直接退出 AC代码: #include<cstdio> #include<cstri ...

  9. 编码问题 php字符编码转换类

    各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...

  10. 给VMware的虚拟机设置静态地址

    最近在VMware 上运行新版本Linux 虚拟机集群,在给每个虚拟机设置静态IP时,遇到一些挫折,新版本有些变动,故记录下来备用. Centos版本信息7.4.1708: Ubuntu版本信息17. ...