抽屉之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
抽屉之Tornado实战(6)--session工厂(工厂方法模式)的更多相关文章
- 抽屉之Tornado实战(1)--分析与架构
抽屉之Tornado实战(1)--分析与架构 项目模拟地址:http://dig.chouti.com/ 知识点应用: AJAX 用于偷偷发请求 原生ajax jQuery ajax($.aj ...
- 抽屉之Tornado实战(9)--装饰器实现用户登录状态验证
当然今天讲的验证,不只Tornado会用,以后用到web框架都会用到,最常见的场景就是只有用户登陆了才能执行某些操作,所以在执行这些操作前要先做登陆状态的验证. 比如:点赞,发布,评论等需要验证,都需 ...
- 抽屉之Tornado实战(5)--点赞与评论树
点赞 点赞的过程:数字增加,并在后台点赞表记录数据 需要发过去的数据:用户id,新闻id 用户id从session里获得,那新闻id怎么获取呢?这想到分页是循环新闻列表来展示内容,循环的新闻id可以做 ...
- 抽屉之Tornado实战(7)--form表单验证
在这里,我们把form表单验证的代码进行工具化了,以后稍微修改一下参数就可以拿来用了 先贴上代码 forms.py from backend.form import fields class Base ...
- 抽屉之Tornado实战(4)--发帖及上传图片
对于链接,点击获取标题时,本质发送ajax请求,然后去链接抓取信息,发布又是发送ajax请求 发布信息,还要有发布者的信息,并在信息表需要记录发布者的用户名,发布者的头像,发布者的id,而这些信息可以 ...
- 抽屉之Tornado实战(3)--注册
知识点应用:标签绑定事件,jQuery获取用户值-->AJAX发送数据-->后台路由系统-->业务逻辑处理-->ORM数据操作-->write返回-->AJAX回调 ...
- 抽屉之Tornado实战(2)--数据库表设计
经过我们上次分析,数据库要有最基本的四张表,用户表,消息表,类型表,点赞表,评论表,接下来我们看着怎么设计吧 首先我们要清楚,表设计的代码是写在models下的 用户表 #一张表对应一个类 class ...
- Tornado实战
抽屉之Tornado实战(1)--分析与架构 抽屉之Tornado实战(2)--数据库表设计 抽屉之Tornado实战(3)--注册 抽屉之Tornado实战(4)--发帖及上传图片 抽屉之Torna ...
- Javascript设计模式理论与实战:工厂方法模式
本文从简单工厂模式的缺点说起,引入工厂方法模式,介绍的工厂方法模式的基本知识,实现要点和应用场景,最后举例进行说明工厂方法模式的应用.在之前的<Javascript设计模式理论与实战:简单工厂模 ...
随机推荐
- linux每日命令(38):iostat命令
Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同 ...
- Angularjs中config中置入以下拦截器
$httpProvider.interceptors.push(['$rootScope', '$q', '$localStorage', function ($rootScope, $q, $loc ...
- Extjs4 DateTimeField,日期时间控件完美版
网上若干类似的控件,要么是有bug,要么是操作体验不合理,这里贡献一个比较科学的版本. 扩展包下载: http://files.cnblogs.com/qidian10/Ext.ux.rar 解压至E ...
- Java知多少(96)绘图之设置字型和颜色
Java绘图中,显示文字的方法主要有三种:(1)drawString(String str,int x,int y):在指定的位置显示字符串.(2)drawChars(char data[],int ...
- Android中Sqlite数据库多线程并发问题
最近在做一个Android项目, 为了改善用户体验,把原先必须让用户“等待”的过程改成在新线程中异步执行.但是这样做遇到了多个线程同时需要写Sqlite数据库,导致操作数据库失败. 本人对Java并不 ...
- #Java学习之路——基础阶段二(第十篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- 【12月26日】A股滚动市盈率PE最低排名
深康佳A(SZ000016) - 滚动市盈率PE:1.47 - 滚动市净率PB:0.98 - 滚动年化股息收益率:4.97% - 消费电子产品 - 深康佳A(SZ000016)的历史市盈率走势图 华菱 ...
- [Converge] Gradient Descent - Several solvers
solver : {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}, default: ‘liblinear’ Algorithm to use in the op ...
- [DQN] What is Deep Reinforcement Learning
已经成为DL中专门的一派,高大上的样子 Intro: MIT 6.S191 Lecture 6: Deep Reinforcement Learning Course: CS 294: Deep Re ...
- [IR] Advanced XML Compression - XBW
思考:与ISX对比后能得出什么结论 原理解析: We proposed the XBW-transform that mimics on trees the nice structural prope ...