原理

1、面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ 、__delitem__、__setitem__方法

2、Tornado框架中,默认执行Handler的get/post等方法之前默认会执行 initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作...

3、session其实就是定义在服务器端用于保存用户回话的容器,其必须依赖cookie才能实现。

4、工厂模式,此非必须

示例

# -*- coding:utf-8 -*-

# SESSION_ENGINE = "session_code.RedisSession"
SESSION_ENGINE = "session_code.CacheSession"
SESSION_ID = "__session_id__"
EXPIRES = 300 REDIS_HOST = '192.168.11.96'
REDIS_PORT = 6379

settings.py

# -*- coding:utf-8 -*-
# 1. "scrapy.middlware.C1"
# import importlib
# path = "scrapy.middlware.C1"
# md,cls = path.rsplit('.',maxsplit=1)
# m = importlib.import_module(md)
# getattr(m,cls)
# 2. 面向对象 # class Foo(object):
#
# def __getitem__(self, item):
# return "123"
#
# def __setitem__(self, key, value):
# pass
#
# def __delitem__(self, key):
# pass
# obj = Foo()
# v = obj['k1']
# print(v)
# obj['k1'] = 666
# del obj['k1'] # request.session['k1'] = 666 # 3.
import time
import hashlib
from . import settings def gen_random_str(): md5 = hashlib.md5()
md5.update(str(time.time()).encode('utf-8'))
return md5.hexdigest() class CacheSession(object): container = {} def __init__(self,handler):
self.handler = handler
self.session_id = settings.SESSION_ID
self.expires = settings.EXPIRES
self.initial() def initial(self):
client_random_str = self.handler.get_cookie(self.session_id)
if client_random_str and client_random_str in self.container:
self.random_str = client_random_str
else:
self.random_str = gen_random_str()
self.container[self.random_str] = {}
expires = time.time()+ self.expires
self.handler.set_cookie(self.session_id,self.random_str,expires=expires) def __getitem__(self, item):
return self.container[self.random_str].get(item) def __setitem__(self, key, value): self.container[self.random_str][key] = value def __delitem__(self, key):
if key in self.container[self.random_str]:
del self.container[self.random_str][key] class RedisSession(object):
def __init__(self,handler):
self.handler = handler
self.session_id = settings.SESSION_ID
self.expires = settings.EXPIRES
self.initial()
@property
def conn(self):
import redis
conn = redis.Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT)
return conn def initial(self):
client_random_str = self.handler.get_cookie(self.session_id) if client_random_str and self.conn.exists(client_random_str):
self.random_str = client_random_str
else:
self.random_str = gen_random_str() expires = time.time()+ self.expires
self.handler.set_cookie(self.session_id,self.random_str,expires=expires)
self.conn.expire(self.random_str,self.expires) def __getitem__(self, item):
import json
data_str = self.conn.hget(self.random_str,item)
if data_str:
return json.loads(data_str)
else:
return None def __setitem__(self, key, value):
import json
self.conn.hset(self.random_str,key,json.dumps(value)) def __delitem__(self, key):
self.conn.hdel(self.random_str,key) class SessionFactory(object):
@staticmethod
def get_session():
from . import settings
import importlib
engine = settings.SESSION_ENGINE
module_path,cls_name = engine.rsplit('.',maxsplit=1)
md = importlib.import_module(module_path)
cls = getattr(md,cls_name)
return cls

mysession.py

#!/usr/bin/env python
# -*- coding:utf-8 -*- import tornado.ioloop
import tornado.web
from tornado.web import RequestHandler
from .mysession import SessionFactory class SessionHandler(object):
def initialize(self, *args, **kwargs):
cls = SessionFactory.get_session()
self.session = cls(self) # CacheSession对象,RedisSession对象 class LoginHandler(SessionHandler,RequestHandler):
# def initialize(self,*args,**kwargs):
# cls = SessionFactory.get_session()
# self.session = cls(self) # CacheSession对象,RedisSession对象
# print(self.session.container) def get(self):
self.render("login.html") def post(self, *args, **kwargs):
user = self.get_argument("user")
pwd = self.get_argument("pwd")
if user == "alex" and pwd == "":
self.session["user"] = user
self.redirect("/index")
else:
self.render("login.html") class IndexHandler(SessionHandler,RequestHandler):
# def initialize(self,*args,**kwargs):
# cls = SessionFactory.get_session()
# self.session = cls(self) # CacheSession对象,RedisSession对象
# # print(self.session.container) def get(self,*args,**kwargs):
user = self.session["user"]
print(user)
if user:
self.write("welcome index")
else:
self.redirect("/login") sett = {
"template_path": "views",
}
application = tornado.web.Application([
(r"/login", LoginHandler),
(r"/index", IndexHandler),
],**sett) # application.reverse_url("n1") if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()

tornado_app.py

1、
def gen_random_str(): # 这个是为了生成随机字符串for session_id
md5 = hashlib.md5()
md5.update(str(time.time()).encode("utf-8"))
return md5.hexdigest() 2、
create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest() 以上均可

补充:random_str

自制session的更多相关文章

  1. Tornado之笔记集合

    目录 一.基本使用 二.路由系统 三.视图函数 四.模版语言 五.cookie 六.CSRF 七.文件上传 八.异步非阻塞 九.RESTFUL 十.自定义组件 一.基本使用 1.最简使用 import ...

  2. 「七天自制PHP框架」第三天:PHP实现的设计模式

    往期回顾:「七天自制PHP框架」第二天:模型与数据库,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 为什么要使用设计模 ...

  3. netcore的Session使用小记

    之前说过,core需要什么功能就添加并使用什么中间件 照例,在Startup.cs的ConfigureServices方法中添加services.AddSession();再在Configure方法中 ...

  4. 自制MVC框架原理介绍

    当初用jsp开发程序时,因为很多东西写在一起混淆的,项目做大或者变更的时候就会很吃力,联动性太大,有时修改视图的东西都可能会影响业务逻辑,分层不明确. 后来听说了Struts MVC,做过几个示例,层 ...

  5. session实现购物车

    为实现简单的购物功能(购物车添加.账户查看.购物车商品删除.实时的购物商品数量及价格的计算显示.购物车商品数量可手动输入等),用session实现了一简单的以php语言为基础.连接MySQL数据库的购 ...

  6. Asp.net Core中使用Session

    前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...

  7. 懒加载session 无法打开 no session or session was closed 解决办法(完美解决)

           首先说明一下,hibernate的延迟加载特性(lazy).所谓的延迟加载就是当真正需要查询数据时才执行数据加载操作.因为hibernate当中支持实体对象,外键会与实体对象关联起来.如 ...

  8. 探索ASP.NET MVC5系列之~~~6.Session篇(进程外Session)

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  9. Nhibernate的Session管理

    参考:http://www.cnblogs.com/renrenqq/archive/2006/08/04/467688.html 但这个方法还不能解决Session缓存问题,由于创建Session需 ...

随机推荐

  1. 第8章 自己写库-构建库函数雏形—零死角玩转STM32-F429系列

    第8章     自己写库—构建库函数雏形 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...

  2. C#引用比较和内容比较

    1.静态方法Object.ReferenceEqual,实际实现为引用比较.   2.静态方法Object.Equal, 实际实现为引用比较.(实际调用了实例方法Equal)   3.Object实例 ...

  3. VRRP虚IP漂移

    简介 VRRP 是 Virtual Router Redundancy Protocol 的简称,即 虚拟路由冗余协议 . 原文地址:https://linux-network-programming ...

  4. ios学习路线—Objective-C(属性修饰符)

    readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...

  5. 在Qtlabel中显示数字十六进制和十进制都可以

    ui->label_6->setText(QString::number(table_test[0]<<8 | table_test[1]));这样子就可以把十六进制的数转换为 ...

  6. Linux服务-ftp

    目录 1. ftp简介 2. ftp架构 3. ftp数据连接模式 4. 用户认证 5. vsftpd 5.1 vsftpd安装 5.2 vsftpd配置 5.3 vsftpd实验配置 5.3.1 安 ...

  7. Mac编译安装swfTools

    Mac编译安装swfTools Mac编译安装swfTools 下载源码 解压源码 安装依赖项 ./configure执行配置或者执行如下配置命令: 需要注意这里存在部分代码错误,需要修改解决后执行 ...

  8. windows从0开始学golang--0--安装golang+git+自己写包

    windows下 1.安装golang 2.安装git(主要是go get 引用git上的包) 3.  使用默认安装生成的目录 pkg:包含包对象,编译好的库文件 src:包含 Go 源文件,注意:你 ...

  9. JavaWeb基础—会话管理之Cookie

    一.什么是会话 打开浏览器,浏览各种资源,点击各种超链接,直至关闭浏览器,整个过程称为会话 二.会话管理的两种技术 1.Cookie 基于客户端.在客户端记录信息来确认用户身份.以cookie的形式写 ...

  10. python列表,元组,字典和字符串之间的相互转换

    元组转换成列表 >>> mytuple = (1,2,3) >>> print list(mytuple) [1, 2, 3] 列表转换成元组 >>&g ...