抽屉之Tornado实战(6)--session工厂(工厂方法模式)

我之前写的session一般保存在服务器的内存里,那可以保存在缓存,或是数据库,那问题来了,不同地方,保存方式是不同的,所以需要定义不同的类,cache/redis/memcached类

session.py

import config
from hashlib import sha1
import os
import time
 
create_session_id = lambda: sha1(bytes('%s%s' % (os.urandom(16), time.time()), encoding='utf-8')).hexdigest()
 
 
class CacheSession:
    session_container = {}
    session_id = "__sessionId__"
 
    def __init__(self, handler):
        self.handler = handler
        client_random_str = handler.get_cookie(CacheSession.session_id, None)
        if client_random_str and client_random_str in CacheSession.session_container:
            self.random_str = client_random_str
        else:
            self.random_str = create_session_id()
            CacheSession.session_container[self.random_str] = {}
 
        expires_time = time.time() + config.SESSION_EXPIRES
        handler.set_cookie(CacheSession.session_id, self.random_str, expires=expires_time)
 
    def __getitem__(self, key):
        ret = CacheSession.session_container[self.random_str].get(key, None)
        return ret
 
    def __setitem__(self, key, value):
        CacheSession.session_container[self.random_str][key] = value
 
    def __delitem__(self, key):
        if key in CacheSession.session_container[self.random_str]:
            del CacheSession.session_container[self.random_str][key]
 
 
class RedisSession:
    def __init__(self, handler):
        pass
 
 
class MemcachedSession:
    def __init__(self, handler):
        pass

把session写死,如果更换session类型,就需要花大量的精力去修改,所以引出今天要说工厂方法模式,在session文件里再定义一个SessionFactory类

class SessionFactory:
 
    @staticmethod
    def get_session_obj(handler):
        obj = None
 
        if config.SESSION_TYPE == "cache":
            obj = CacheSession(handler)
        elif config.SESSION_TYPE == "memcached":
            obj = MemcachedSession(handler)
        elif config.SESSION_TYPE == "redis":
            obj = RedisSession(handler)
        return obj

并在配置文件里写入你要使用的session类型,每次修改时只需修改配置文件

settings.py

# Session类型:cache/redis/memcached
SESSION_TYPE = "cache"
# Session超时时间(秒)
SESSION_EXPIRES = 60 * 20

在Tornado里,RequestHandler类提供一个initialize方法,用于在实例handler对象之前执行的,我们在这个方法里创建session对象,并赋给handler对象self.session这普通字段

 

request_handler.py

import tornado.web
from backend.session.session import SessionFactory
 
 
class BaseRequestHandler(tornado.web.RequestHandler):
 
    def initialize(self):
 
        self.session = SessionFactory.get_session_obj(self)

执行流程:

  前端访问url-->路由系统对应handler类-->执行initialize方法(创建self.session普通字段)-->执行session.py下SessionFactory的静态方法get_session_obj-->根据配置文件给定值,实例化session对象,并return

 

代码详解  

from hashlib import sha1
import os
import time
import config
 
#构造生成session随机字段串的函数
create_session_id = lambda: sha1(bytes('%s%s' % (os.urandom(16), time.time()), encoding='utf-8')).hexdigest()
 
 
class SessionFactory:
    #静态方法直接由类调用
    @staticmethod
    def get_session_obj(handler):
        obj = None
 
        if config.SESSION_TYPE == "cache":
            obj = CacheSession(handler)
        elif config.SESSION_TYPE == "memcached":
            obj = MemcachedSession(handler)
        elif config.SESSION_TYPE == "redis":
            obj = RedisSession(handler)
        return obj
 
 
class CacheSession:
    #用于存储session键值对的字典
    session_container = {}
    #指定前端存储cookie时key
    session_id = "__sessionId__"
 
    def __init__(self, handler):
        self.handler = handler
        #前端cookie {"__sessionId__":"session随机字符串"}
        client_random_str = handler.get_cookie(CacheSession.session_id, None)
        #如果能获取到session随机字符串而且也在服务器内存里
        if client_random_str and client_random_str in CacheSession.session_container:
            #把获取的随机串赋给self.random_str
            self.random_str = client_random_str
        else:
            #没有就生成一个随机串
            self.random_str = create_session_id()
            #后台服务器{"session随机串":{...}}
            CacheSession.session_container[self.random_str] = {}
 
        #设置过期时间
        expires_time = time.time() + config.SESSION_EXPIRES
        #并写入到cookie
        handler.set_cookie(CacheSession.session_id, self.random_str, expires=expires_time)
 
    def __getitem__(self, key):
        #self.session[key]
        ret = CacheSession.session_container[self.random_str].get(key, None)
        return ret
 
    def __setitem__(self, key, value):
        #self.session[key] = value
        CacheSession.session_container[self.random_str][key] = value
 
    def __delitem__(self, key):
        #del self.session[key]
        if key in CacheSession.session_container[self.random_str]:
            del CacheSession.session_container[self.random_str][key]
 
 
class RedisSession:
    def __init__(self, handler):
        pass
 
 
class MemcachedSession:
    def __init__(self, handler):
        pass

 

转载于:https://www.cnblogs.com/zcok168/p/9797680.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值