|簡體中文

比思論壇

 找回密碼
 按這成為會員
搜索



查看: 434|回復: 0
打印 上一主題 下一主題

解决Dropbox中国无法及时自动同步的问题

[複製鏈接]

21

主題

0

好友

141

積分

小學生

Rank: 2

  • TA的每日心情
    擦汗
    2023-8-15 22:30
  • 簽到天數: 334 天

    [LV.8]以壇為家I

    推廣值
    0
    貢獻值
    0
    金錢
    242
    威望
    141
    主題
    21
    樓主
    發表於 2012-4-20 00:34:58

    最近由于想要使用Dropbox的多人协作功能,就发现Dropbox不能自动同步其他机器上产生的文件变化,经过一番搜索,发现原来是GFW在作怪(GFW和GD的性质和用心我们心知肚明,就不在这里评价了)。月光博客发布了解决Dropbox无法实时更新的问题分析了产生这个问题的原因并提出一个有效的解决方案。但是在使用时我发现,我找不到一个优良稳定的代理服务器,也没工夫去学习privoxy软件的配置和使用,而且我要将解决方案提供给我的合伙人,一个复杂的方案是不能接受的。经过一番研究,提出如下比较简单的办法。

      分析

      我发现Dropbox向notify8发出的请求很简单,回应也很简单,一共有两种:{"ret":"new"}和{"ret":"punt"}

      分别表示云端有变化和无变化,然后客户端考虑去下载文件列表并同步。

      经过一番痛苦的失败,我发现这个请求的其实是一个comet请求,服务器端并不马上回应,而是会挂起,如果有变化,则马上回应,如果一直没有变化,大约一分钟超时回应punt,然后客户端再连接服务器。在我分析Dropbox的过程中一直不解:为什么Dropbox的其他请求都是https,而只有这一个请求是http的。现在找到了答案:因为它是comet请求,长连接,而且连接频率非常高,如果使用https代价太大,而且影响效率。如果这个请求返回new,客户端就会使用https连接服务器端。

      解决

      由此提出一个完美的解决方案,不仅可以解决本机的问题,而且可以解决朋友的问题,只要让朋友修改hosts为我的ip地址:

    • 修改hosts将notify8对应的ip地址改为本机
    • 在本机建立一个http服务,代理notify8得到dropbox的返回值,再原封不动地返回给本机dropbox客户端

      具体方法是使用tornado,进行一步http请求,这样只占用很少一部分系统资源。贴出代码。

      代码

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    from tornado.options import define, options
    from tornado import httpclient


    define("port", default=8888, help="run on the given port", type=int)


    class Application(tornado.web.Application):
        def __init__(self):
            handlers = [
                (r"/subscribe", NotifyHandler),
                (r"/.*", HomeHandler),
            ]
            settings = dict(
                debug=True,
            )
            self.debug = True
            tornado.web.Application.__init__(self, handlers, **settings)


    class HomeHandler(tornado.web.RequestHandler):
        def get(self):
            self.set_header("Content-Type", "text/plain")
            self.write("Hello from Tornado!")


    class NotifyHandler(tornado.web.RequestHandler):
        @tornado.web.asynchronous
        def get(self):
            self.set_header("Content-Type", "text/plain")
            url = xxxxx #关键代码还是不贴出来了,人怕出名猪怕壮,要是大多数人会用了,估计这个方法死期不远矣!
            http_client = httpclient.AsyncHTTPClient()
            http_client.fetch(url, self.handle_response, request_timeout=100.0)

        def handle_response(self, response):
            if response.error:
                print "Can not connect."
                self.write("{\"ret\": \"new\"}")
            else:
                print "Connect Successfull."
                self.write(response.body)
            self.finish()


    def main():
        tornado.options.parse_command_line()
        http_server = tornado.httpserver.HTTPServer(Application())
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()

    if __name__ == "__main__":
        main()


    重要聲明:本論壇是以即時上載留言的方式運作,比思論壇對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,讀者及用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,讀者及用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本論壇受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者及用戶發現有留言出現問題,請聯絡我們比思論壇有權刪除任何留言及拒絕任何人士上載留言 (刪除前或不會作事先警告及通知 ),同時亦有不刪除留言的權利,如有任何爭議,管理員擁有最終的詮釋權。用戶切勿撰寫粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。

    手機版| 廣告聯繫

    GMT+8, 2024-9-22 13:42 , Processed in 0.017660 second(s), 26 queries , Gzip On.

    Powered by Discuz! X2.5

    © 2001-2012 Comsenz Inc.

    回頂部