以下介绍都是建立在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,我们可以做什么?的更多相关文章

  1. Tornado基于MiddleWare做中间件

    详细代码如下: 在app.py里添加 # -*- coding:utf-8 -*- from tornado.ioloop import IOLoop from tornado.web import ...

  2. 深入理解Tornado——一个异步web服务器

    本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...

  3. [tornado]websocket 最简单demo

    想法 前两天想看看django 长轮询或者是websocket的方案,发现都不太好使. tornado很适合做这个工作,于是找了些资料,参照了做了个最简单demo,以便备用. 具体的概念就不说了,to ...

  4. tornado架构分析1 从helloworld分析tornado架构

    最近公司需要我写一个高性能RESTful服务组件.我之前很少涉及这种高性能服务器架构,帮公司和平时没事玩都是写脚本级别的东西.虽然好多基础组件(sphinx.logging.configparse等) ...

  5. Python的Tornado框架的异步任务与AsyncHTTPClient 

    转载自http://www.php.cn/python-tutorials-284773.html 高性能服务器TornadoPython的web框架名目繁多,各有千秋.正如光荣属于希腊,伟大属于罗马 ...

  6. python的高性能web应用的开发与测试实验

    python的高性能web应用的开发与测试实验 tornado“同步和异步”网络IO模型实验 引言 python语言一直以开发效率高著称,被广泛地应用于自动化领域: 测试自动化 运维自动化 构建发布自 ...

  7. 一个使用 asyncio 开发的网络爬虫(译文)

    原文地址:https://www.aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html 作者简介 A. Jesse Jiryu ...

  8. tornado做简单socket服务器(TCP)

    http://blog.csdn.net/chenggong2dm/article/details/9041181 服务器端代码如下: #! /usr/bin/env python #coding=u ...

  9. tornado框架学习及借用有道翻译api做自动翻译页面

    趁着这几天有时间,就简单的学了一下tornado框架,简单做了个自动翻译的页面 仅为自己学习参考,不作其他用途 文件夹目录结构如下: . ├── server.py ├── static │   └─ ...

随机推荐

  1. 微信企业号 获取AccessToken

    目录 1. AccessToken介绍 2. 示例代码 1. AccessToken介绍 1.1 什么是AccessToken AccessToken即访问凭证,业务服务器每次主动调用企业号接口时需要 ...

  2. Jenkins 安装的HTML Publisher Plugin 插件无法展示ant生成的JunitReport报告

    最近在做基于jenkins ant  junit 的测试持续集成,单独ant junit生成的junitreport报告打开正常,使用Jenkins的HTML Publisher Plugin 插件无 ...

  3. Tcp/ip 报文解析

    在编写网络程序时,常使用TCP协议.那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送.下面我们来看看几种协议头的构成 一 .Ethe ...

  4. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

  5. async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  6. Partition1:新建分区表

    未分区的表,只能存储在一个FileGroup中:对Table进行分区后,每一个分区都存储在一个FileGroup,或分布式存储在不同的FileGroup中.对表进行分区的过程,是将逻辑上完整的一个表, ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(73)-微信公众平台开发-消息管理

    系列目录 前言 回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂 你也可以按自己所分析的情形结构来建表 必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较 ...

  8. 浏览器中用JavaScript获取剪切板中的文件

    本文转自我的个人网站  , 原文地址:http://www.zoucz.com/blog/2016/01/29/get-file-from-clipboard/  ,欢迎前往交流讨论 在网页上编辑内容 ...

  9. CRL快速开发框架系列教程五(使用缓存)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  10. C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素”

    Q: 在反序列化 Xml 字符串为 Xml 对象时,抛出如下异常. 即在 XML文档(0, 0)中有一个错误:缺少根元素. A: 首先看下代码: StringBuilder sb = new Stri ...