V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hard2reg
V2EX  ›  Python

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

  •  
  •   hard2reg · 2016-06-20 21:08:36 +08:00 · 2909 次点击
    这是一个创建于 2859 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我看了 @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()
    

    output

    第 1 条附言  ·  2016-06-21 02:32:20 +08:00

    现在都可以正常试用了。就是在线听必须的整首缓冲好才行。。还有就是速度太慢,应该是阻塞了。。自己根据手册瞎加了什么协程?不知道这样子对不对。。希望得到高人指点。。

    https://gist.github.com/PythonFu/a48936ac1267e128881a1d725e3dddf8

    8 条回复    2016-06-21 13:34:53 +08:00
    hard2reg
        1
    hard2reg  
    OP
       2016-06-20 21:11:44 +08:00
    hard2reg
        2
    hard2reg  
    OP
       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
        3
    qq316107934  
       2016-06-21 00:55:24 +08:00 via Android   ❤️ 1
    mark ,刚刚躺下,明天下午来看
    hard2reg
        4
    hard2reg  
    OP
       2016-06-21 01:09:56 +08:00
    @qq316107934 我发现问题了,我这样写不是加载不出来,是必须得等整个首歌缓冲完才能听。。。。
    SlipStupig
        5
    SlipStupig  
       2016-06-21 09:09:52 +08:00
    @hard2reg 用 requests 是堵塞的,要么用 tornado 自带的 http 客户端异步请求,要么用 gevent 去 patch
    cloverstd
        6
    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
        7
    yangtukun1412  
       2016-06-21 09:49:08 +08:00
    tornado 的异步模型是基于 epoll 封装的 ioloop, 和 gevent 的协程是两码事.
    sujin190
        8
    sujin190  
       2016-06-21 13:34:53 +08:00
    你应该用 tornado 的 AsyncClient ,并且好像 AsyncClient 是可以下载一部分来个回调你发给客户端就行,如果还不行,你直接用 IOStream 连也可以啊, IOStream 每下载一部分就会回调
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5291 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:49 · PVG 13:49 · LAX 22:49 · JFK 01:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.