最近在维护项目的时候,发现某个实时数据同步功能非常容易失败,故静下心来彻底弄清楚该设计的实现原理,以及其中用到的python异步sockethandler : asyncore。

实时数据同步功能的设计非常简单,用户在网页上触发某个记录的"Sync Up" button, 后台把该记录的id和type传入asyncore Client,asyncore Client把信息传入local的另一个asyncore server进程,asyncore server端调用相应的同步数据API,进行同步,并把同步的数据信息(包括同步过程的log和status)写入数据库;同时在click button的时候,会触发一个循环的js call,不断发出异步请求,获取存入的实时同步log信息,把log信息打印到页面上,更新progress bar。

asyncore Client:

class Client(asyncore.dispatcher_with_send):
def __init__(self, host, port, message):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
self.out_buffer = message
self.response = '' def handle_close(self):
self.close() def handle_read(self):
self.response = self.recv(1024)
self.close() def send(command):
c = Client('127.0.0.1', 8081, command)
asyncore.loop()
return c.response if __name__ == '__main__':
send('quit')

asyncore server

class asyncoreServer(asyncore.dispatcher):

    def __init__(self, address, handlerClass=ServerHandler):
print ">>> Server Socket init with address:%s:%s" % (address[0], address[1])
self.address = address
self.handlerClass = handlerClass
self.address_family = socket.AF_INET
self.socket_type = socket.SOCK_STREAM
self.request_queue_size = 5
self.allow_reuse_address = True asyncore.dispatcher.__init__(self)
self.create_socket(self.address_family,self.socket_type) if self.allow_reuse_address:
self.set_reuse_addr() self.server_bind()
self.server_activate() def server_bind(self):
self.bind(self.address)
log.debug("bind: address=%s:%s" % (self.address[0], self.address[1]))
print ">>> Begin bind server" def server_activate(self):
self.listen(self.request_queue_size)
log.debug("listen: backlog=%d" % self.request_queue_size) def fileno(self):
return self.socket.fileno() def serve_forever(self):
asyncore.loop() def handle_accept(self):
(conn_sock, client_address) = self.accept()
print "Receive Client request socket=%s, client_address=%s:%s" % (conn_sock, client_address[0], client_address[1])
if self.verify_request(conn_sock, client_address):
self.process_request(conn_sock, client_address) def verify_request(self, conn_sock, client_address):
return True def process_request(self, conn_sock, client_address):
log.info("conn_made: client_address=%s:%s" % (client_address[0],client_address[1]))
self.handlerClass(conn_sock, client_address, self) def handle_close(self):
self.close()

关于asyncore的介绍:

asyncore库是python的一个标准库,它是一个异步socket的包装。

asyncore提供一个方法和一个基类:loop()方法和dispatcher基类。

每一个继承dispatcher的类的对象,都可以看做一个需要处理的Socket,可以是TCP也可以是UDP,子类override一些dispatcher的方法,主要是重写‘handle_’打头的方法,比如:

handle_connect, handle_close,  handle_read, handle_write ...

loop()方法负责检查一个dict, dict中保存dispatcher的实例,这个字典被称为channel。每次创建一个dispatcher对象,都会把自己加入到一个默认的dict里面去(当然也可以自己指定channel)。当对象被加入到channel中的时候,socket的行为都已经被定义好,程序只需要调用loop(),一切功能就实现了。

reference:

https://docs.python.org/2/library/asyncore.html

采用asyncore进行实时同步的更多相关文章

  1. lsyncd 实时同步

    1. 几大实时同步工具比较 1.1 inotify + rsync 最近一直在寻求生产服务服务器上的同步替代方案,原先使用的是inotify + rsync,但随着文件数量的增大到100W+,目录下的 ...

  2. 烂泥:rsync与inotify集成实现数据实时同步更新

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 上篇文章我们介绍了如何使用rsync同步文件,这篇文章我们再来介绍下,如何把rsync与inotify集成实现数据的实时同步. 要达到这个目的,我们需要 ...

  3. Rsync+Inotify-tools实现数据实时同步

    inotify是一种强大的,细粒度的,异步文件系统时间监控机制,它可以替代crond实现与rsync的触发式文件同步,从而监控文件系统中添加,删除,修改,移动等细粒事件,从LINUX 2.6.13起, ...

  4. rsync+inotify实现服务器之间文件实时同步--转

    之前做了“ssh信任与scp自动传输脚本”的技术文档,此方案是作为公司里备份的方法,但在实际的运行中,由于主服务器在给备份服务器传输的时候,我们的主服务器需要备份的文件是实时.不停的产生的,造成不知道 ...

  5. linux下两台服务器文件实时同步方案设计和实现

    inux下两台服务器文件实时同步方案设计和实现 假设有如下需求: 假设两个服务器: 192.168.0.1 源服务器  有目录 /opt/test/ 192.168.0.2 目标服务器  有目录 /o ...

  6. hexo建立github,gitcafe博客并实时同步的要点

    把hexo博客的源码和生成的页面实时同步到github和gitcafe. 用搜索引擎搜索"github 博客"等关键字会出现大量很好的文章教小白一步步搭建.我这里列出一些关键点,希 ...

  7. lsyncd —— 多机器实时同步文件神器

    lsyncd 是一个支持实时.双向.多机器的多模式文件同步工具. 使用 Lua 语言封装了 inotify 和 rsync 工具,采用了 Linux 内核(2.6.13 及以后)里的 inotify ...

  8. rsync+inotify实现实时同步案例【转】

    1.1 inotify介绍 inotify是一种强大的.细粒度的.异步的文件系统事件控制机制.linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加.删除. ...

  9. sersync基于rsync+inotify实现数据实时同步

    一.环境描述 需求:服务器A与服务器B为主备服务模式,需要保持文件一致性,现采用sersync基于rsync+inotify实现数据实时同步 主服务器A:192.168.1.23 从服务器B:192. ...

随机推荐

  1. Real Adaboost总结

    Real Adaboost分类器是对经典Adaboost分类器的扩展和提升,经典Adaboost分类器的每个弱分类器仅输出{1,0}或{+1,-1},分类能力较弱,Real Adaboost的每个弱分 ...

  2. 斐波那契数[XDU1049]

    Problem 1049 - 斐波那契数 Time Limit: 1000MS   Memory Limit: 65536KB   Difficulty: Total Submit: 1673  Ac ...

  3. CSS Counters 计数属性

    CSS Counters其实就是一计数器,早期在CSS中计数器仅存在于ul和ol元素.如果要使用在div这样的元素上,只能通过list-style-image或者是元素的backgroud-image ...

  4. 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1834 我又思考人生了T_T,nd的数组开小了,一直wa,调了一个小时才发现啊!!!!!我一直以为我的 ...

  5. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

  6. redis_查找命令

    1:文件名查找 find -name "filename" filename可以用通配符 2:文件内行数查找 在vi模式下 ,刚进入vi 输入:128(linenum)   即能跳 ...

  7. CSS透明度大汇总

    近年来,CSS不透明算得上是一种相当流行的技术,但在跨浏览器支持上,对于开发者来说,可以说是一件令人头疼的事情.目前还没有一个通用方法,以确保透明度设置可以在目前使用的所有浏览器上有效. 这篇汇总主要 ...

  8. lvs原理和实战

     lvs-dr原理 lvs-nat原理:  当我们的网站流量越来越大时一台web服务器已经无法满足需求了,我们该如何解决呢??把服务器连接起来实现负载均衡或许是个不错的办法..下面我就来看看怎么实现吧 ...

  9. 一些开发遇到的"小问题",你能答对多少?

    我会把问题先写在前面,答案用白色字体写在后面.所以用鼠标选择文本就可以看到答案啦. 调用await后因为切换了线程环境(这种说法可能不严谨,但我只能想到这种说法),httpcontext会为null. ...

  10. 找1到n所有整数出现1的个数

    编程之美2.4 n=12时,1,11,12这3个数包含1,所以1的个数是5. Line 9是为了防止factor溢出. #include <iostream> #include <s ...