egnchen / pyQQRobot

基于Python3与WebQQ协议的QQ机器人框架 A QQ robot framework based on WebQQ and Python3.
32 stars 6 forks source link

这真的、真的是个问题 #15

Closed WuTianming closed 8 years ago

WuTianming commented 8 years ago

怎么终止listening... 我想加一个自动重启功能

我首先将qqhttp_gevent.py里的mHTTPClient_gevent._gevent_req()

f = self.opener.open(r)

改成了

f = self.opener.open(r, timeout=5)

这样就能够每隔五秒钟检测一下“停止”标记是否设置,而不是一直堵塞;

接下来,我将qqrobot.pylisten()里面创建线程的代码改了下,大概是这样:

class l(threading.Thread):
    def __init__(self, qcli, poll_headers):
        threading.Thread.__init__(self)
        self.poll_headers = poll_headers
        self.qcli = qcli
        self._running = True
    def run(self):
        log.i('listener', 'Listener thread started.')
        while self._running:
            log.i('listener', 'Still running, start of loop.')
            print(str(threading.enumerate()))
            # 上面这行列出所有线程以便debug
            r = self.qcli.http_client.req(
                url_poll2, data=d, headers=self.poll_headers)
            self.qcli._callback_receive(
                r, {'url': url_poll2,
                    'data': d, 'headers': self.poll_headers})
            log.i('listener', 'Still running, end of loop.')
        log.i('listener', 'Listener thread stopped.')
    def cancel(self):
        # C中的线程结束是cancel,我就直接用这个命名了,虽然感觉用terminate命名会更好
        log.i('STOP', 'going to stop')
        self._running = False
        self.join()

self.t = l(self, self.poll_headers)
self.t.start()
if join:
    self.t.join()

(作为一个新手,我也不知道是不是有问题...)

然后在listen()的下面添加了一个极其简单的listen_stop()

def listen_stop(self):
    self.t.cancel()

这就算是改造完成了。然而,调用listen_stop会出现一些很玄学的情况,就是线程显示已经退出,但实际上还在运行... 有时间再来补充,再去debug一会

WuTianming commented 8 years ago

问题原因原来在于我重复执行了add_handler导致每次重启之后对消息的响应次数增多,误以为是前面的线程没关

唉,每次bug都这么隐蔽