最近在维护项目的时候,发现某个实时数据同步功能非常容易失败,故静下心来彻底弄清楚该设计的实现原理,以及其中用到的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. ural 1217. Unlucky Tickets

    1217. Unlucky Tickets Time limit: 1.0 secondMemory limit: 64 MB Strange people live in Moscow! Each ...

  2. BZOJ1580 : [Usaco2009 Hol]Cattle Bruisers 杀手游戏

    以贝茜为参照物,则贝茜固定于原点,每个杀手是一个圆心在某条射线上的圆. 解出每个杀手可以射杀贝茜的时间区间,然后扫描线即可,时间复杂度$O(n\log n)$. #include<cstdio& ...

  3. BZOJ2610 : [Poi2003]Monkeys

    考虑离线,将删边操作倒过来变成加边,等价于询问每个点什么时候与1连通 使用并查集维护,每次合并时如果有一边是1所在连通块,就把另一边的所有点的答案更新 #include<cstdio> # ...

  4. BZOJ 1067 & Interval_Tree

    1067: [SCOI2007]降雨量 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3099 Solved: 800 Description 我们常常 ...

  5. android 蓝牙4.0多通道

    很久没记录东西了,前段时间研究了一哈android4.0控制多个外设的情况,注意,需要使用android版本4.3以上,蓝牙4.0及以上. 我这里使用的控制蓝牙灯泡,使用android4.3的手机,手 ...

  6. 【wikioi】1004 四子连棋

    题目链接 算法:BFS //2014-02-05更新 *******************************2013-10-15******************************* ...

  7. HttpClient工具类v1.7

    package com.cucpay.fundswap.util; import java.io.IOException; import java.net.SocketTimeoutException ...

  8. 关于后台管理linkbutton按钮几个重要属性的理解

    <asp:LinkButton ID="lkbtnDelete" runat="server" CausesValidation="False& ...

  9. people 0919

    package liu0919; public class People { private double height;// 身高 private String name;// 名字 private ...

  10. getattr的作用是什么呢

    在python的官方文档中:getattr()的解释如下:getattr(object, name[, default]) Return the value of the named attribut ...