Passed
Push — master ( 53c413...1211a5 )
by Taosikai
15:08
created

MessageHandler::onMessage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the slince/smartqq package.
5
 *
6
 * (c) Slince <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Slince\SmartQQ;
13
14
15
use GuzzleHttp\Exception\ConnectException;
16
use Slince\EventDispatcher\DispatcherInterface;
17
use Slince\EventDispatcher\Event;
18
use Slince\SmartQQ\Exception\InvalidArgumentException;
19
use Slince\SmartQQ\Exception\ResponseException;
20
use Slince\SmartQQ\Exception\RuntimeException;
21
22
class MessageHandler
23
{
24
    /**
25
     * 事件名,当收到消息时触发.
26
     *
27
     * @var string
28
     */
29
    const EVENT_MESSAGE = 'message';
30
31
    /**
32
     * @var Client
33
     */
34
    protected $client;
35
36
    /**
37
     * @var DispatcherInterface
38
     */
39
    protected $eventDispatcher;
40
41
    /**
42
     * 可以被忽略的状态码.
43
     *
44
     * @var array
45
     */
46
    protected static $ignoredCodes = [
47
        0, 100003, 100100, 100012
48
    ];
49
50
    public function __construct(Client $client)
51
    {
52
        $this->client = $client;
53
        $this->eventDispatcher = $client->getEventDispatcher();
54
    }
55
56
    /**
57
     * 绑定消息处理回调
58
     *
59
     * ```php
60
     * $handler->onMessage(function(Slince\SmartQQ\Message\Response\Message $message){
61
     *      //...
62
     * });
63
     * ```
64
     *
65
     * @param callable $handler
66
     */
67
    public function onMessage($handler)
68
    {
69
        if (!is_callable($handler)) {
70
            throw new InvalidArgumentException('Message handler should be callable.');
71
        }
72
        $this->eventDispatcher->addListener(static::EVENT_MESSAGE, function(Event $event) use ($handler){
73
            $handler($event->getArgument('message'));
74
        });
75
    }
76
77
    /**
78
     * 开始监听客户端消息
79
     */
80
    public function listen()
81
    {
82
        while (true) {
83
            try {
84
                $messages =  $this->client->pollMessages();
85
                if ($messages) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $messages of type Slince\SmartQQ\Message\Response\Message[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
86
                    foreach ($messages as $message) {
87
                        // 收到消息时触发事件
88
                        $event = new Event(static::EVENT_MESSAGE, null, [
89
                            'message' => $message
90
                        ]);
91
                        $this->eventDispatcher->dispatch($event);
92
                    }
93
                } else {
94
                    //延缓2秒
95
                    usleep(2000000);
96
                }
97
            } catch (ResponseException $exception) {
98
                if (in_array($exception->getCode(), static::$ignoredCodes)) {
99
                    $this->testLogin();
100
                }
101
            } catch (ConnectException $exception) {
102
                usleep(2000000);
103
            }
104
        }
105
    }
106
107
    /**
108
     * 测试登录
109
     */
110
    protected function testLogin()
111
    {
112
        try {
113
            $this->client->getFriendsOnlineStatus();
114
        } catch (ResponseException $exc) {
115
            //登录凭证可能失效
116
            throw new RuntimeException('The credential may be expired, please login again.', $exc->getCode());
117
        }
118
    }
119
}