使用tornado,我们可以做什么?
以下介绍都是建立在python2.x的基础上面,tornado使用任意版本皆可。
如果我们需要对外提供一个http server(web api)/websocket server时,我们都可以使用tornado,以下是一个基于tornado的rest的应用简介。
当我们下载好了tornado以后,可以按照tornado的文档demo,复制一份监听代码过来,代码如下:
- import tornado.ioloop
- import tornado.web
- class MainHandler(tornado.web.RequestHandler):
- def get(self):
- self.write("Hello, world")
- application = tornado.web.Application([
- (r"/", MainHandler),
- ])
- if __name__ == "__main__":
- application.listen(8888)
- tornado.ioloop.IOLoop.instance().start()
这一段代码在运行时就已经可以开始监听并返回信息了,然后开始按照rest的规范开始改写,我们首先需要对url的path进行定位,根据path执行相对应的代码,则有了以下代码:
- import os.path
- import tornado.escape
- import tornado.ioloop
- import tornado.options
- import tornado.web
- import tornado.websocket
- import tornado.httpserver
- import tools
- import applogic
- from config import config
- class Application(tornado.web.Application):
- def __init__(self):
- handlers = [
- (r"/.*?", WebHandler),
- ]
- settings = dict(
- cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
- template_path=os.path.join(os.path.dirname(__file__), "templates"),
- static_path=os.path.join(os.path.dirname(__file__), "static"),
- xsrf_cookies=False
- )
- tornado.web.Application.__init__(self, handlers, **settings)
- class WebHandler(tornado.web.RequestHandler):
- def get(self):
- path = self.request.path
- command = path[path.rfind('/') +1:]
- result = applogic.execute(self, command, self.get_argument)
- if result:
- to_message = tools.dumps(result)
- self.write(to_message)
- def post(self):
- path = self.request.path
- command = path[path.rfind('/') +1:]
- obj = tools.loads(self.request.body)
- result = applogic.execute(self, command, obj)
- if result:
- to_message = tools.dumps(result)
- self.write(to_message)
- def main():
- app = Application()
- http_server = tornado.httpserver.HTTPServer(app)
- http_server.bind(config.default['main_port'], config.default['host'])
- tornado.ioloop.IOLoop.instance().start()
我们对path做了最后一级目录的截取,由于客观原因,多级目录的则需要看客们自行实现。
applogic是我们的具体的逻辑代码门面类,因为是脚本语言的关系,所以这里使用一个相对巧妙的ioc,代码如下:
- def execute(handler, command, obj):
- if main_map.has_key(command):
- result = main_map[command](handler, obj)
- if result:
- response.send(handler, result)
- else:
- handler.send_error(404)
- def create(handler, obj):
- flag = papercache.push(obj)
- result = {}
- if flag:
- result = {
- 'code':0
- }
- else:
- result = {
- 'code':1,
- 'errorMsg':'param is error'
- }
- return result
- def grab(handler, obj):
- id = obj.has_key('id') and obj['id'] or None
- result = {
- 'code':1,
- 'errorMsg':'redpaper is empty',
- 'money':0
- }
- if id:
- money = papercache.pop_queue(id)
- if money:
- result = {
- 'money' : money,
- 'code': 0
- }
- return result
- main_map = {
- 'create':create,
- 'grab':grab
- }
我们将具体的执行逻辑,放在定义好的function里面,然后将function的引用放在一个字典里面,然后根据command(最后一级目录对应的字符串),来执行具体的代码。
我们将返回的数据做了一个封装,因为实际应用里面的数据格式,可能采用的是json,或者是其它自定义的协议,所以我们有一个response的封装,代码如下:
- def send(handler, obj):
- if type(handler) is not None:
- obj = tools.dumps(obj)
- handler.write(obj)
tools的代码如下:
- import json
- def dumps(obj):
- obj = toUnicode(obj)
- if obj:
- obj = json.dumps(obj)
- obj = str(obj)
- return obj
- def loads(obj):
- if obj:
- obj = json.loads(str(obj))
- obj = toUtf8(obj)
- return obj
因为可能存在中文的关系,所以加了一个Utf8的转换,,基于websocket的也是同理,则在监听的时候,使用WebSocketHandle,代码如下:
- import os.path
- import tornado.escape
- import tornado.ioloop
- import tornado.options
- import tornado.web
- import tornado.websocket
- import tornado.httpserver
- import tools
- import applogic
- from config import config
- class Application(tornado.web.Application):
- def __init__(self):
- handlers = [
- (r"/web", MainHandler)
- (r"/.*?", WebHandler),
- ]
- settings = dict(
- cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
- template_path=os.path.join(os.path.dirname(__file__), "templates"),
- static_path=os.path.join(os.path.dirname(__file__), "static"),
- xsrf_cookies=False
- )
- tornado.web.Application.__init__(self, handlers, **settings)
- class MainHandler(tornado.websocket.WebSocketHandler):
- def allow_draft76(self):
- return True
- def open(self):
- token = self.get_cookie('token')
- if not token:
- print "long not token"
- self.close()
- else:
- print('connect')
- def on_close(self):
- print('close');
- def on_message(self, message):
- obj = tools.loads(message)
- command = obj.has_key('command') and obj['command'] or None
- body = obj.has_key('body') and obj['body'] or None
- result = applogic.execute(self, command, body)
- if result:
- to_message = tools.dumps(result)
- self.write(to_message)
- return
- class WebHandler(tornado.web.RequestHandler):
- def get(self):
- path = self.request.path
- command = path[path.rfind('/') +1:]
- result = applogic.execute(self, command, self.get_argument)
- if result:
- to_message = tools.dumps(result)
- self.write(to_message)
- def post(self):
- path = self.request.path
- command = path[path.rfind('/') +1:]
- obj = tools.loads(self.request.body)
- result = applogic.execute(self, command, obj)
- if result:
- to_message = tools.dumps(result)
- self.write(to_message)
- def main():
- app = Application()
- http_server = tornado.httpserver.HTTPServer(app)
- http_server.bind(config.default['main_port'], config.default['host'])
- tornado.ioloop.IOLoop.instance().start()
可能你们会觉得怎么多了个command和body出来了,因为我的通讯协议是假定{"command":"", "body":""},这样的json格式。
那一个简易的基于python的rest服务和websocket通讯服务器到这里就结束了
使用tornado,我们可以做什么?的更多相关文章
- Tornado基于MiddleWare做中间件
详细代码如下: 在app.py里添加 # -*- coding:utf-8 -*- from tornado.ioloop import IOLoop from tornado.web import ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- [tornado]websocket 最简单demo
想法 前两天想看看django 长轮询或者是websocket的方案,发现都不太好使. tornado很适合做这个工作,于是找了些资料,参照了做了个最简单demo,以便备用. 具体的概念就不说了,to ...
- tornado架构分析1 从helloworld分析tornado架构
最近公司需要我写一个高性能RESTful服务组件.我之前很少涉及这种高性能服务器架构,帮公司和平时没事玩都是写脚本级别的东西.虽然好多基础组件(sphinx.logging.configparse等) ...
- Python的Tornado框架的异步任务与AsyncHTTPClient
转载自http://www.php.cn/python-tutorials-284773.html 高性能服务器TornadoPython的web框架名目繁多,各有千秋.正如光荣属于希腊,伟大属于罗马 ...
- python的高性能web应用的开发与测试实验
python的高性能web应用的开发与测试实验 tornado“同步和异步”网络IO模型实验 引言 python语言一直以开发效率高著称,被广泛地应用于自动化领域: 测试自动化 运维自动化 构建发布自 ...
- 一个使用 asyncio 开发的网络爬虫(译文)
原文地址:https://www.aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html 作者简介 A. Jesse Jiryu ...
- tornado做简单socket服务器(TCP)
http://blog.csdn.net/chenggong2dm/article/details/9041181 服务器端代码如下: #! /usr/bin/env python #coding=u ...
- tornado框架学习及借用有道翻译api做自动翻译页面
趁着这几天有时间,就简单的学了一下tornado框架,简单做了个自动翻译的页面 仅为自己学习参考,不作其他用途 文件夹目录结构如下: . ├── server.py ├── static │ └─ ...
随机推荐
- Android UI体验之全屏沉浸式透明状态栏效果
前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体 ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- WinForm 天猫2013双11自动抢红包【源码下载】
1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login ...
- 【.net 深呼吸】程序集的热更新
当一个程序集被加载使用的时候,出于数据的完整性和安全性考虑,程序集文件(在99.9998%的情况下是.dll文件)会被锁定,如果此时你想更新程序集(实际上是替换dll文件),是不可以操作的,这时你得把 ...
- javascript匹配各种括号书写是否正确
今天在codewars上做了一道题,如下 看上去就是验证三种括号各种嵌套是否正确书写,本来一头雾水,一种括号很容易判断, 但是三种怎么判断! 本人只是个前端菜鸟,,不会什么高深的正则之类的. 于是,在 ...
- ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录
升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...
- Android之网络数据存储
一.网络保存数据介绍 可以使用网络来保存数据,在需要的时候从网络上获取数据,进而显示在App中. 用网络保存数据的方法有很多种,对于不同的网络数据采用不同的上传与获取方法. 本文利用LeanCloud ...
- Spring异步功能
使用 Spring 的异步功能时,实质是使用的 Servlet3 及以上版本的异步功能. Spring 的异步处理机制需要在 web.xml 中全部的 servlet 和 filter 处配置 < ...
- Maven(一)linux下安装
1.检查是否安装JDK,并且设置了环境变量(JAVA_HOME): echo $JAVA_HOME java -version 运行结果: 显示jdk的安装路径,和java的版本,如: #jdk路径 ...
- gulp 自动添加版本号
本文介绍利用 gulp-rev 和 gulp-rev-collector 进行版本管理 npm官网介绍使用后的效果如下: "/css/style.css" => " ...