抽屉之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设计模式理论与实战:简单工厂模 ...
随机推荐
- WebService学习总结——调用第三方提供的webService服务
互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的Web应用中显示,下面就以获取天气预报数据. 气象中心的管理系统将收 ...
- Java知多少(34)final关键字:阻止继承和多态
在 Java 中,声明类.变量和方法时,可使用关键字 final 来修饰.final 所修饰的数据具有“终态”的特征,表示“最终的”意思.具体规定如下: final 修饰的类不能被继承. final ...
- html页面工具-htmlUnit
HtmlUnit测试工具的推出,创意非常好.是一款给java开发用的browser.说它是browser,其实它是对html建模并且提供API来访问页面,点击链接等等的java类库. 这样的测 ...
- PI SQL 语句
insert [piarchive]..[picomp2](tag,time,value) values('ppnie_test','t',100) INSERT into pipoint..clas ...
- Linux目录详细说明大全(推荐)
Linux目录详细说明大全,方便你以后合理规划及管理 "/" : 根目录Linux文件系统的入口.也是最高级,最重要的的目录.除衍生出其它目录,还和系统的开机,还原,系统修复有的, ...
- MySQL主从介绍 准备工作 配置主 配置从 测试主从同步
配置主: • 安装mysql • 修改my.cnf,增加server-id=130和log_bin=xiaobo1 • 添加环境变量 Vim /root/.bash_profile PATH=$PAT ...
- 用Physijs在场景中添加物理效果
1.创建可用Physijs的基本Three.js场景 创建一个可用Physijs的Three.js场景非常简单,只要几个步骤即可.首先我们要包含正确的文件, 需要引入physi.js文件.实际模拟物理 ...
- A股ROE连续3年超过15%的股票排名
R连续3年,12个季度的滚动ROE,都超过15%的股票排名,个股滚动ROE = 最近4个季度的归母净利润 / ((期初归母净资产 + 期末归母净资产) / 2). 查看更多ROE连续3年超过15%的股 ...
- duilib进阶教程 -- 在MFC中使用duilib (1)
由于入门教程的反响还不错,因此Alberl就以直播的形式来写<进阶教程>啦,本教程的前提: 1.请先阅读<仿迅雷播放器教程> 2.要有一定的duilib基础,如果还没,请先阅读 ...
- Inside The C++ Object Model(一)
============================================================================1-1. 关键字struct和class的一点区 ...