以下介绍都是建立在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. 在.NET Core 里使用 BouncyCastle 的DES加密算法

    .NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...

  2. PHP的学习--RSA加密解密

    PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...

  3. Mysql存储引擎比较

    Mysql作为一个开源的免费数据库,在平时项目当中会经常使用到,而在项目当中我们的着重点一般在设计使用数据库上而非mysql本身上,所以在提到mysql的存储引擎时,一般都不曾知道,这里经过网上相关文 ...

  4. Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)

    概要 这篇博客是在上一篇博客Phantomjs+Nodejs+Mysql数据抓取(1.抓取数据) http://blog.csdn.net/jokerkon/article/details/50868 ...

  5. [开发笔记] Graph Databases on developing

    TimeWall is a graph databases github It be used to apply mathematic model and social network with gr ...

  6. 敏捷测试模式之Scrum及其实践

    一.    敏捷开发模式简介 敏捷是近年来软件研发领域很火的一个词,采用敏捷开发模式的研发团队是越来越多了,尤其是敏捷模式中的Scrum更是佼佼者大行其道,这表明敏捷模式确有其好处,能给企业带来效率的 ...

  7. could not initialize proxy - no Session

    这是一个精典的问题:因为我们在hibernate里面load一个对象出来时,用到的是代理对象,也就是说当我们在执行load方法时并没有发sql语句,而是返回一个proxy对象.只有当们具体用到哪个ge ...

  8. Linux1 在Linux(CentOS)上安装MySql详细记录

    前记:  毕业两年了,前两天换了份工作,由以前的传统行业跳到了互联网行业.之前的公司一直在用WinServer2003+Tomcat+SqlServer/Oracle这套部署环境.对于Linux+To ...

  9. 《深入理解Java虚拟机》类文件结构

    上节学习回顾 在上一节当中,主要以自己的工作环境简单地介绍了一下自身的一些调优或者说是故障处理经验.所谓百变不离其宗,这个宗就是我们解决问题的思路了. 本节学习重点 在前面几章,我们宏观地了解了虚拟机 ...

  10. 站在风口,你或许就是那年薪20w+的程序猿

    最近面试了一些人,也在群上跟一些群友聊起,发现现在的互联网真是热,一些工作才两三年的期望的薪资都是十几K的起,这真是让我们这些早几年就成为程序猿的情何以堪!正所谓是站在风口上,猪也能飞起来!我在这里就 ...