day23-Tornado
一,安装方法:
# pip3 install tornado
二,基本使用:
1、路由系统
a、原生支持restful\
b、二级域名
application.add_handlers("cmdb.oldboy.com",[
(r"/main", CmdbHandler),
])
c、动态
# Author:Alex Li #!/usr/bin/env python # -*- coding:utf-8 -*- # pip3 install tornado import tornado.ioloop import tornado.web import hashlib import time def md5(arg): m = hashlib.md5() m.update(bytes(arg,encoding='utf-8')) return m.hexdigest() app_id_list = [ '1suidfmsdfoj', '1su5451254212' ] visited_api = [ "http://www.oldboy.com:8888/api?app_id=8e69354826691f0ea816d7108be7c122|1477194640.0149357" ] class MainHandler(tornado.web.RequestHandler): def get(self): app_id = self.get_argument('app_id',None) md, current_time = app_id.split('|') server_current_time = time.time() client_current_time = float(current_time) if client_current_time< server_current_time-10: self.write('滚') return # 10s以内发送的数据 # 正常用户发送请求: 11:10:10 # 服务器请求: 11:10:12 if app_id in visited_api: self.write('滚') return # current_time客户端的当前时间 # 服务器的当前事件 # 将黑客随便写的url过滤 flag = False for key in app_id_list: new_str = "%s|%s" %(key, current_time) server_md = md5(new_str) if md == server_md: # redis,10s之后就小时 visited_api.append(app_id) flag = True break if flag: self.write('ok') else: self.write('滚') application = tornado.web.Application([ (r"/api", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
2、模版引擎
- 功能更接近python
- 母板
- uimethods
- uimodules
# Author:Alex Li from tornado.web import UIModule # from tornado import escape class custom(UIModule): def javascript_files(self): return ['http://assdfasdfasdf.js','http://11111.js',] def embedded_javascript(self): return "function f1(){alert(123);}" def css_files(self): pass def embedded_css(self): pass def render(self, *args, **kwargs): return "<h1>CCCC</h1>"
3、cookie
请求cookie和响应cookie
明文,加密
set_cookie(k,'alex')
set_cookie(k,'alex')
# 加密:
1、当前时间戳
2、内容
3、md5
# 服务器:key
# 字符串拼接
new_str = 1477191363.8245482|key ====》base64加密
# 新字符串md5
md5(new_str)
# md5(new_str)|alex|1477191363.8245482
md5(1477191363.8245482)
# asdfasdfasdfasdfasdfasdf|alex
# asdfasd234234234asdfasdf|alex
代码:
#!/usr/bin/env python # -*- coding:utf-8 -*- # pip3 install tornado import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): # self.write("Hello, world") # 头、内容、cookie # self.get_argument() # self.set_cookie() # self.get_cookie() # # self.set_secure_cookie() # self.get_secure_cookie() # 获取所有的请求头 # self._headers self.set_header('k','v') self.render('main.html', li=[11,22,33,44]) class CmdbHandler(tornado.web.RequestHandler): def get(self): self.write("cmdb") import xo import ox settings = { 'template_path': 'views', 'ui_methods':xo, 'ui_modules':ox, } application = tornado.web.Application([ (r"/main", MainHandler), ],**settings) application.add_handlers("cmdb.oldboy.com",[ (r"/main", CmdbHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
4、请求头,相应头
...
5、自定义Session:
a.
def index(request):
request.session['k'] = 123
request.seeeion['k']
del request.session['k']
class Foo:
def __getitem__(key):
return 123
def __setitem__(key,value):
pass
def __delitem__(key):
pass
obj = Foo()
ret = obj['xxx']
obj['xxxx'] = 123
del obj['xxxx']
b. tornado的扩展点
class BaseHandler(tornado.web.RequestHandler):
def initialize(self):
self.sss = {'k': 123}
class MainHandler(BaseHandler):
def get(self):
print(self.sss)
self.write('ok')
c. Session原理
# Author:Alex Li import hashlib import time from Session import conf class SessionHandler: def initialize(self): self.session_obj = SessionFacotory.get_session_obj(self) class SessionFacotory: @staticmethod def get_session_obj(handler): if conf.session_type == 'redis': return RedisSession(handler) elif conf.session_type == 'memcache': return RedisSession(handler) else: return MemorySession(handler) def md5(): m = hashlib.md5() m.update(bytes(str(time.time()),encoding='utf-8')) return m.hexdigest() class MemorySession: container = { } # self.r_str当前用户的随机字符串 def __init__(self,handler): random_str = handler.get_cookie('___session_id___') if random_str: # 客户端有cookie # 合法cookie if random_str in MemorySession.container: self.r_str = random_str else: # 非法cookie random_str = md5() MemorySession.container[random_str] = {} self.r_str = random_str else: # 客户端无cookie,表示是新用户的到来 random_str = md5() MemorySession.container[random_str] = {} self.r_str = random_str handler.set_cookie('___session_id___', random_str, expires=time.time() + 200) def __setitem__(self, key, value): MemorySession.container[self.r_str][key] = value def __getitem__(self, item): return MemorySession.container[self.r_str].get(item,None) def __delitem__(self, key): del MemorySession.container[self.r_str][key] class RedisSession: def __init__(self): pass def __getitem__(self, item): pass def __setitem__(self, key, value): pass def __delitem__(self, key): pass
6、自定义form表单验证
# Author:Alex Li #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web import re class InputText: def __str__(self): return '<input type="text" />' class InputPassword: def __str__(self): return '<input type="password" />' class StringField: reg = "^\w+$" def __init__(self,w=None): self.w = w if w else InputText() def match(self): pass def __str__(self): return str(self.w) class StringListField: reg = "^\w+$" def __init__(self): pass def match(self): pass class EmailField: reg = "^\w+$" def __init__(self): pass class IndexForm: def __init__(self): self.user = StringField() self.pwd = StringField(w=InputPassword()) def is_valid(self,handler): flag = True for k,v in self.__dict__.items(): # k="user" v="^\w+$" StringField对象 # k="pwd" v="^\w+$" EmailField对象 if type(v) == StringListField: input_value = handler.get_arguments(k) else: input_value = handler.get_argument(k) result = v.match(input_value) if not result: flag = False return flag class IndexHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): form = IndexForm() self.render('index.html', form=form) def post(self, *args, **kwargs): form = IndexForm() ret = form.is_valid(self) print(ret) settings = { 'template_path': 'views' } application = tornado.web.Application([ (r"/index.html", IndexHandler), ], **settings) if __name__ == "__main__": print('http://127.0.0.1:8005') application.listen(8005) tornado.ioloop.IOLoop.instance().start()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form method="post" action="/index.html"> {% raw form.user %} #生成html非字符串 {% raw form.pwd %} <hr > <input type="text" name="user" /> <input type="text" name="pwd" /> <input type="submit" value="提交" /> </form> </body> </html>
7、异步非阻塞
装饰器 + Future 从而实现Tornado的异步非阻塞
# Future容器,默认hung住请求,等待用户向future中发送数据
# hung住: Http未断开;Tornado可以单线程去操作其他请求
# self.finish()
使用:
1、add_time,设置等待时间
2、Future,添加回调函数,设置值,不再hung住 *******************
3、httpclient类库
class AsyncHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): future = Future() future.add_done_callback(self.doing) yield future # 或 # tornado.ioloop.IOLoop.current().add_future(future,self.doing) # yield future def doing(self,*args, **kwargs): self.write('async') self.finish()
- 示例聊天室:
发现聊天室,连接不断开:
- 轮训 ,setInterval
# Author:Alex Li # Author:Alex Li #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web import time import json class IndexHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): self.render('index.html') li = [ {'id':123123, 'content': 'asdfasdfasdf'} ] class MsgHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): index = self.get_argument('index') index = int(index) if index == 0: self.write(json.dumps(li)) else: self.write(json.dumps(li[index:])) settings = { 'template_path': 'views', 'static_path': 'static', } application = tornado.web.Application([ (r"/index.html", IndexHandler), (r"/msg.html", MsgHandler), ], **settings) if __name__ == "__main__": print('http://127.0.0.1:8006') application.listen(8006) tornado.ioloop.IOLoop.instance().start()
- 长轮训,实例:::::::对异步非阻塞的应用 必须会
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="container"> </div> <script src="/static/jquery-1.12.4.js"></script> <script> INDEX = 0; function get_message(){ $.ajax({ url: '/msg.html', type: 'get', data: {'index': INDEX}, dataType: 'json', success: function (arg) { $.each(arg, function(k,v){ INDEX +=1; var tag = document.createElement('p'); tag.innerHTML = v.content; $('#container').append(tag); }); get_message() } }) } get_message() </script> </body> </html>
- websocket
8、方案
用户权限管理
- 普通用户
- 销售
- 讲师
====》 Django