slince / smartqq

:penguin: SmartQQ (原 WebQQ ) API 的 PHP 语言实现,提供了一系列更优雅可读性更高的API
MIT License
82 stars 27 forks source link

在调用pollMessages方法监听消息时会异常 #21

Closed pgyf closed 3 years ago

pgyf commented 6 years ago

测试隔几秒会异常腾讯接口返回code为0 从这里看到 https://github.com/pandolia/qqbot/blob/31b464ef05849696b150363492776d64e050c244/qqbot/basicqsession.py#L207 https://github.com/pandolia/qqbot/issues/145 (0, 100003, 100100, 100012) 这些code都可以排除,不用抛异常 调用下获取好友状态测试下登录就行了 这些我在外部try解决了

轮询消息http接口不好用我参考这里用了https https://github.com/pandolia/qqbot/blob/31b464ef05849696b150363492776d64e050c244/qqbot/basicqsession.py#L198

这里用获取好友在线状态测试登录过期 https://github.com/pandolia/qqbot/blob/31b464ef05849696b150363492776d64e050c244/qqbot/basicqsession.py#L174

pgyf commented 6 years ago

经过修改,从登录一直挂着4个小时一直正常,只不过每隔一分钟就得调用下获取好友在线状态 20180921155115

slince commented 6 years ago

不知道方不方便提供下 这块代码,我准备加入到api里,帮用户做轮询

pgyf commented 6 years ago

大概就是这样子的 我参考py的了

    public function listen() {
        Logger::log('开始接收消息');
        $time = 0;
        while (true) {
            try {
                //心跳
                $time = $this->heartbeat($time);
                $messages =  $this->smartQQ->pollMessages();
            } catch (ResponseException $exc) {
                if (in_array($exc->getCode(), [0, 100003, 100100, 100012])) { 
                    $this->testLogin();
                    continue;
                }
            }
            if ($messages) {
                $this->printR('收到消息' . PHP_EOL);
                foreach ($messages as $message) {
                       //代码省略用的示例中的
                }
            } else {
                //延缓2秒
                usleep(2000000);
            }
        }
    }

    /**
     * make a heartbeat every 30 minutes.
     * 半个小时心跳
     * @param $time
     * @return int
     */
    private function heartbeat($time) {
        if (time() - $time > 1800) {
            $user = Config::get('heartbeat_usernick'); //我根据自己配置的昵称给这个人发一个消息
            $friend = $this->friends->firstByAttribute('nick', $user);
            if (!empty($friend)) {
                $content = '随机表情(自己写了个获取随机表情的方法)'. ' heart beat ' . date('Y-m-d H:i:s');
                $message = new \Slince\SmartQQ\Message\Request\FriendMessage($friend, $content);
                $this->smartQQ->sendMessage($message);
            }
            return time();
        }

        return $time;
    }

    /**
     * 测试登录
     */
    private function testLogin() {
        try {
            $this->smartQQ->getFriendsOnlineStatus();
            Logger::log('获取好友在线状态正常');
        } catch (ResponseException $exc) {
            //登录凭证可能失效
            Logger::log('登录凭证可能失效 code:' . $exc->getCode() . ' 异常:' . $exc->getMessage(), Logger::TYPE_ERROR);
            throw new \Exception('登录凭证可能失效', $exc->getCode());
        }
    }
slince commented 6 years ago

心跳操作我看py版并没有,是不是可以省略

pgyf commented 6 years ago

好像没有 我是把微信机器人的 拿过来改了下。可以省略,主要是用户就知道机器人是不是正常这里

slince commented 6 years ago

ok

slince commented 5 years ago

2.2.0-beta1 增加了message handler; 你可以试下有没有什么其他问题 https://github.com/slince/smartqq/blob/master/src/MessageHandler.php

example 有用法

pgyf commented 5 years ago

2.2.0-beta1 挂了1个小时没有掉线,目前没有发现问题