月光博客 » 软件应用 » 解决Dropbox中国无法及时自动同步的问题

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

  最近由于想要使用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()

  来源:投稿,原文链接

顶一下 ▲()   踩一下 ▼()

相关文章

  1. 1
      说道:
    今天貌似很多国外服务器的网站都打不开
    fklal 于 2012-4-5 5:30:00 回复
    是的。真是气愤。
    fklal 于 2012-4-5 5:30:33 回复
    今天跟昨天一直是这样。连Live,微软都打不开。
    wozhenshangxin 于 2012-4-5 13:18:27 回复
    我这边是只要不是大陆站点都上不去……
    支持(29反对(19回复
  1. 2
    聋的传人   说道:
    3月29日Google Analytics无法访问,部分用户访问时出现白屏。主要原因是为GA提供CSS文件资源的ssl.gstatic.c om域名被某墙阻塞。
    支持(25反对(15回复
  1. 3
    激灵网   说道:
    博主:
    和你说一个最新的消息,昨天下午6点开始 湖南中国电信一直访问不上国外的网站,其他省市都可以访问。请问是不是电信的问题 刚才致电了10000说可能是国外服务器的问题。
    mvke 于 2012-4-5 20:54:56 回复
    中国移动的网络也出现这样的问题,我是今天上午上班发现的。估计是gfw又抽风了。
    支持(29反对(22回复
  1. 4
    mlfwhan   说道:
    同意LSD。。。一起。
    支持(22反对(18回复
  1. 5
    Felix   说道:
    我想问,如果用这个解决方案的话,局域网内的LAN同步会失效么?
    支持(9反对(5回复
  1. 6
    JJ   说道:
    谁会编程帮忙写一个东西啊?
    支持(28反对(25回复
  1. 7
    newbob   说道:
    对我来说还是太专业了,看不懂。但问题解决不了,真着急呀!我操他死妈的砖制!
    支持(9反对(7回复
  1. 8
    James   说道:
    你好,请问如果我想让ipad能够同步dropbox该怎么做?
    支持(7反对(7回复
  1. 9
    liworld   说道:
    据说要输入中文
    Notify8.dropbox点COM has one IP number (199.47.217.148). Sjc-not8.sjc.dropbox点COM point to the same IP.
    支持(7反对(8回复
  1. 10
    123   说道:
    有道理,会的人太多,就不管用了。所以,为了防止那些可能让它不管用的人,就让所有人都不知道好了。。但是,为什么要说前半部分,什么都不说,不是效果更好?
    支持(27反对(29回复
  1. 11
    JimmyZ   说道:
    楼主的意思就是, 给懂技术的人一点启发, 真让人写成傻瓜教程了, 就太容易了
    支持(15反对(17回复
  1. 12
    mvke   说道:
    4楼的人说得对,我写这篇文章主要是给会用python的人做一个参考,要是工信部觉得很多人都在用一个方法,那就不灵了。大家还是努力提高自己的翻墙技术水平吧。
    支持(16反对(18回复
  1. 13
    爱易读   说道:
    我是来打酱油的。。。
    支持(17反对(19回复
  1. 14
    用电器   说道:
    没看懂,本机不能直接访问dropbox http的话,在本机架设代理也还是不能访问啊。代理服务器必须是能够直接访问目标的机器吧?还是说没有贴出来的那部分代码里有什么玄机,直接链接到某个服务器了?
    我试了一下ping notify*发现是能够ping通的,返回IP也是美国地址,就是不知道是否为其真实IP。如果是网址关键字匹配,是否直接修改本机的notify服务器host即可实现状态更新,而无需设置代理?
    因为不懂python所以只能写这些了,不知作者能否指教……
    支持(4反对(6回复
  1. 15
    victorwoo   说道:
    在windows下要怎么实践,如何使用这段代码,能给一下说明么?
    支持(5反对(7回复
  1. 16
    RadeonLEI   说道:
    广西电信也上不了,不停的登录下线换IP后,偶尔某个可以上某些国外网站。
    支持(17反对(20回复
  1. 17
    hezudao   说道:
    啊~我不会编程语言……
    支持(10反对(14回复
  1. 18
    很恶心的窝里斗   说道:
    发现个有意思的现象, 最近发现联通官网10010 打不开, 我家用的电信宽带, 但是通过翻墙越过电信的GF*W后,发现能迅速打开10010, 以为是巧合,反复实验后发现确实如此。
    支持(20反对(27回复

发表留言