需求: 我们需要监控客户端是否已经掉线, 采用的做法是客服端定时发送消息到 socket server. 我们在socket server确认是否已经收到心跳消息,如果超时(timeout)则会剔除相应的客户端。
为此,我们准备在python抽象出原型雏形。熟悉Javascript的可能知道定时器函数setTimeout,setInterval.
我们在Python(2.7)也可有类似功能: 如下:
def set_interval(func,extraArgs,sec): def func_wrapper(): func(*extraArgs) t = threading.Timer(sec, func_wrapper) t.start() return t
下一步,为每一个客服端连接(session)建立一个AliveThread来处理,第一次客户端连接来的时候,push msg(msgId, timestamp,...); 第二次来的时候,pop(delete )msg and append msg. 为此,有了
MsgManager这样的消息汇总,我们就能在一个monitor function中处理掉线.
为此,我们又需要类似java里面的Vector,ConcurrentHashMap来确保MsgManager线程操作安全。
如下:
from multiprocessing import Process, Manager manager = Manager() MsgManager = manager.list()
好了,剩下的很简单了:
set_interval(monitor,[self._msg],NO_MSG_RECEIVED_AFTER_INTERVAL) def monitor(tmpMsg): log.info('kick out')
需求2: 为了给客服端最快的响应,我们从多个服务端获取信息,最快返回的信息将返回给客户。
为此,我们用 package concurrent:
# python2.7.x 安装 https://pypi.python.org/packages/source/f/futures/futures-2.1.6.tar.gz#md5=cfab9ac3cd55d6c7ddd0546a9f22f453 # python3.x 自带 from concurrent import futures import urllib2 SERVICES = ['http://host1/service', 'http://host2/service', 'http://host3/service', 'http://host4/service'] def load_url(url, timeout): return urllib2.urlopen(url, timeout=timeout).read() with futures.ThreadPoolExecutor(max_workers=5) as executor: future_to_url = dict((executor.submit(load_url, url, 60), url) for url in SERVICES) for future in futures.as_completed(future_to_url): url = future_to_url[future] if future.exception() is None: print('url: %s,content:%s' % (url, future.result())) break