Redis简易聊天室

import redis
import json
import hashlib


class RedisUtil(object):
    def __init__(self):
        self.chat_room_nick_set = 'chat_room_nick_set'
        self.cookie_nick = 'cookie-{}'
        self.chat_list = 'chat_list'

        # 初始化Redis
        self.client = redis.Redis()

    def is_nick_already_exists(self, nick):
        """
        判断这个昵称是不是已经登录过了。如果已经登录,那么就不能使用这个昵称。

        使用Redis的集合实现,如果把昵称sadd到集合中返回1,说明这个昵称之前
        不存在,此时应该返回False,如果返回0,表示这个昵称之前已经存在了,此时应该返回True。

        :param nick: 昵称
        :return: True or False
        """
        is_flag = self.client.sadd(self.chat_room_nick_set, nick)
        if is_flag == 1:
            return False
        return True

    def set_token(self, nick, token):
        """
        设定Token,这样的好处是只需要登录一次,以后可以直接访问/room页面直接进入聊天窗口

        使用Redis的字符串实现,字符串的Key是"cookie-昵称",例如"cookie-青南",值为参数token
        :param nick: 昵称
        :param token: md5字符串
        :return: None
        """
        key = self.cookie_nick.format(nick)
        self.client.set(key, token)

    def get_token(self, nick):
        """
        获取Token,从"cookie-昵称"token并返回。

        使用Redis的字符串实现,字符串的Key为"cookie-昵称",例如"cookie-青南",如果这个Key存在,
        就获取它的值并返回,如果这个Key不存在,就返回None
        :param nick: 昵称
        :return: None 或者 Token字符串
        """
        key = self.cookie_nick.format(nick)
        token = self.client.get(key)
        return None if not token else token.decode()

    def get_chat_list(self):
        """
        获取聊天消息列表。

        使用Redis的列表实现。Key为self.chat_list属性中保存的字符串,可以直接使用。
        获取列表右端20条信息,但不要删除。

        需要注意,从Redis中获取的数据一个列表,列表里面是bytes型的字符串,所以需要
        先把这个列表展开,把里面的bytes型的字符串解密为普通字符串以后再用json解析为
        字典。接下来讲解析出来的字典放入一个新的列表中。最后返回新的列表。
        :return: 包含字典的列表
        """
        chat_list = self.client.lrange(self.chat_list, -20, -1)
        chat_info_list = []
        for chat in chat_list:
            chat_info = json.loads(chat)
            chat_info_list.append(chat_info)
        return chat_info_list

    def get_nick_msg_expire_time(self, nick, msg):
        """
        获取某一个昵称发送某一条消息的过期时间。这个功能的作用是
        为了防止同一个用户短时间发送大量相同信息刷屏。

        为了防止信息太长,因此把信息编码为md5以后再与昵称拼接以缩短Key的长度。
        使用Redis的ttl命令来实现,ttl命令如果返回None,说明不存在这个Key,
        返回None。如果ttl返回-1,说明这个Key没有设定过期时间,这个Key可以一直存在
        如果ttl返回一个大于0的正整数,说明在这个整数对应的秒过于以后,Redis会自动
        删除这个Key

        :param nick: 昵称
        :param msg: 信息
        :return: None 或者 数字
        """
        msg_md5 = hashlib.md5(msg.encode()).hexdigest()
        duplicate_msg_check_flag = nick + msg_md5
        expire_time = self.client.ttl(duplicate_msg_check_flag)
        return expire_time

    def push_chat_info(self, chat_info):
        """
        把聊天信息存入列表的右侧。

        使用Redis的集合实现,对应的Key为self.chat_list中保存的字符串。
        把chat_info字典先转化为JSON字符串,再存入Redis中列表中。

        为了防止列表消息太长,因此需要使用ltrim命令删除多余的信息,只保留
        列表最右侧的20条
        :param chat_info: 字典,格式为{'msg': '信息', 'nick': '青南', 'post_time': '2018-07-22 10:00:12'}
        :return: None
        """
        self.client.rpush(self.chat_list, json.dumps(chat_info))
        self.client.ltrim(self.chat_list, -20, -1)
    

    def set_nick_msg_expire_time(self, nick, msg):
        """
        设定Key的过期时间,这个功能的目的是限定同一个用户在2分钟内不能发送同样的内容。

        为了防止信息太长,因此把信息编码为md5以后再与昵称拼接以缩短Key的长度。

        使用Redis的字符串实现,字符串的Key为昵称+信息的md5编码,值为1.使用set命令的
        ex参数设定Key的过期时间为120秒,时间到了以后Redis会自动删除这个Key
        :param nick: 昵称
        :param msg: 信息
        :return: None
        """
        msg_md5 = hashlib.md5(msg.encode()).hexdigest()
        duplicate_msg_check_flag = nick + msg_md5
        self.client.set(duplicate_msg_check_flag, 1, ex=120)

运行截图:
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值