在学习 tornado 的时候遇到的一个小问题

2016-06-20 21:08:36 +08:00
 hard2reg

我看了 @qq316107934 发的一个帖子,他使用 tornado 写了一个代理服务器。于是本人新手 就作死学起了 tornado 。但是发现我点击一次歌手的时候会执行两次 post 函数感觉好奇怪,不知道为什么。。。

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

import tornado.ioloop
import tornado.web
from tornado.web import RequestHandler

class MainHandler(RequestHandler):
	def get(self):
		self.write('Hello world')

class NetEaseHandler(RequestHandler):
	def post(self, url):
		print('%s Hacked' % url, '\n')
		print(dict(self.request.headers), '\n')
		print(self.request.body, '\n')

def make_app():
	return tornado.web.Application([
		(r'/', MainHandler),
		(r'( http://music.163.com/eapi/v1/.*)', NetEaseHandler)
	])

if __name__ == '__main__':
	app = make_app()
	app.listen(8080)
	tornado.ioloop.IOLoop.current().start()

2912 次点击
所在节点    Python
8 条回复
hard2reg
2016-06-20 21:11:44 +08:00
hard2reg
2016-06-20 23:50:12 +08:00
新问题,在无法缓冲。。。

```Python
# -*- coding: utf-8 -*-

import tornado.ioloop
import tornado.web
from tornado.web import RequestHandler
import requests

def getResponse(url, headers, body):
r = requests.post(url, headers=headers, data=body)
return r.content

class MainHandler(RequestHandler):
def get(self):
self.write('Hello world')

class NetEaseHandler(RequestHandler):
def get(self, url):
print('%s Hacked' % url, '\n')
# print(dict(self.request.headers), '\n')
# print(self.request.body, '\n')
r = getResponse(url, dict(self.request.headers), self.request.body)
self.write(r)

def post(self, url):
print('%s Hacked' % url, '\n')
# print(dict(self.request.headers), '\n')
# print(self.request.body, '\n')
r = getResponse(url, dict(self.request.headers), self.request.body)
self.write(r)

class NetEaseApiHandler(RequestHandler):
def get(self, url):
print('%s Hacked' % url, '\n')
# print(dict(self.request.headers), '\n')
# print(self.request.body, '\n')
r = getResponse(url, dict(self.request.headers), self.request.body)
self.write(r)

def post(self, url):
print('%s Hacked' % url, '\n')
# print(dict(self.request.headers), '\n')
# print(self.request.body, '\n')
r = getResponse(url, dict(self.request.headers), self.request.body)
self.write(r)

def make_app():
return tornado.web.Application([
(r'/', MainHandler),
(r'( http://music.163.com/eapi/.*)', NetEaseApiHandler),
(r'(.*)', NetEaseHandler)
])

if __name__ == '__main__':
app = make_app()
app.listen(8080)
tornado.ioloop.IOLoop.current().start()
```
qq316107934
2016-06-21 00:55:24 +08:00
mark ,刚刚躺下,明天下午来看
hard2reg
2016-06-21 01:09:56 +08:00
@qq316107934 我发现问题了,我这样写不是加载不出来,是必须得等整个首歌缓冲完才能听。。。。
SlipStupig
2016-06-21 09:09:52 +08:00
@hard2reg 用 requests 是堵塞的,要么用 tornado 自带的 http 客户端异步请求,要么用 gevent 去 patch
cloverstd
2016-06-21 09:33:53 +08:00
感觉不理解 Tornado 的 epoll ,很容易 block 的


@hard2reg 因为你的代码里是先到网易服务器把整首歌下好,再 write 到你的浏览器

用 Tornado 的 AsyncHTTPClient ,然后配合 self.write 和 self.flush
如果用 Nginx 做代理,可能还需 self.set_header('X-Accel-Buffering', 'no') 这个 header
yangtukun1412
2016-06-21 09:49:08 +08:00
tornado 的异步模型是基于 epoll 封装的 ioloop, 和 gevent 的协程是两码事.
sujin190
2016-06-21 13:34:53 +08:00
你应该用 tornado 的 AsyncClient ,并且好像 AsyncClient 是可以下载一部分来个回调你发给客户端就行,如果还不行,你直接用 IOStream 连也可以啊, IOStream 每下载一部分就会回调

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/287129

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX