• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ringcentral / ringcentral-php / 5130932145

pending completion
5130932145

push

github

web-flow
feat: websocket subscription support (#122)

* feat: support websocket subscription

* chore: update webhook demo

* misc: use Exception

* chore: update phpunit.xml

* fix: syntax error at php 7.4

* misc: refactor and add tests for websocket

* chore: require react/async at dev

* chore: add tests for ws subscription

* chore: add more tests

* chore: add more tests

216 of 216 new or added lines in 11 files covered. (100.0%)

664 of 732 relevant lines covered (90.71%)

30.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.47
/src/WebSocket/Subscription.php
1
<?php
2

3
namespace RingCentral\SDK\WebSocket;
4

5
use Exception;
6
use RingCentral\SDK\Platform\Platform;
7
use RingCentral\SDK\WebSocket\WebSocket;
8
use RingCentral\SDK\WebSocket\ApiException;
9
use RingCentral\SDK\WebSocket\ApiResponse;
10
use RingCentral\SDK\WebSocket\ApiRequest;
11
use RingCentral\SDK\WebSocket\Events\ErrorEvent;
12
use RingCentral\SDK\WebSocket\Events\NotificationEvent;
13
use RingCentral\SDK\WebSocket\Events\SuccessEvent;
14
use RingCentral\SDK\Subscription\SubscriptionBase;
15

16
class Subscription extends SubscriptionBase
17
{
18
    /** @var WebSocket */
19
    protected $_webSocket;
20

21
    function __construct(Platform $platform, WebSocket $webSocket)
22
    {
23
        $this->_webSocket = $webSocket;
12✔
24
        parent::__construct($platform);
12✔
25
    }
26

27
    /**
28
     * @return bool
29
     */
30
    public function subscribed()
31
    {
32
        return (!empty($this->_subscription) &&
12✔
33
                !empty($this->_subscription['id']));
12✔
34
    }
35

36
    /**
37
     * @param array $options
38
     *
39
     * @throws Exception
40
     *
41
     * @return Subscription
42
     */
43
    public function subscribe(array $options = [])
44
    {
45
        if (!empty($options['events'])) {
6✔
46
            $this->setEvents($options['events']);
3✔
47
        }
48
        try {
49
            $request = new ApiRequest([
6✔
50
                'method' => 'POST',
6✔
51
                'path'   => '/restapi/v1.0/subscription',
6✔
52
                'body' => [
6✔
53
                    'eventFilters' => $this->getFullEventFilters(),
6✔
54
                    'deliveryMode' => [
6✔
55
                        'transportType' => 'WebSocket'
6✔
56
                    ]
6✔
57
                ]
6✔
58
            ]);
6✔
59
            $response = $this->_webSocket->sendRequest($request, function (ApiResponse $response) {
6✔
60
                if (!$response->ok()) {
6✔
61
                    $exception = new ApiException($response);
3✔
62
                    $this->dispatch(new ErrorEvent($exception), self::EVENT_SUBSCRIBE_ERROR);
3✔
63
                    return;
3✔
64
                }
65
                $this->setSubscription($response->body());
3✔
66
                $this->dispatch(new SuccessEvent($response), self::EVENT_SUBSCRIBE_SUCCESS);
3✔
67
            });
6✔
68
        } catch (Exception $e) {
×
69
            $this->reset();
×
70
            throw $e;
×
71
        }
72
    }
73

74
    public function renew(array $options = [])
75
    {
76
        if (!empty($options['events'])) {
9✔
77
            $this->setEvents($options['events']);
3✔
78
        }
79

80
        if (!$this->subscribed()) {
9✔
81
            throw new Exception('No subscription');
3✔
82
        }
83

84
        try {
85
            $request = new ApiRequest([
6✔
86
                'method' => 'PUT',
6✔
87
                'path' => '/restapi/v1.0/subscription/' . $this->_subscription['id'],
6✔
88
                'body' => [
6✔
89
                    'eventFilters' => $this->getFullEventFilters(),
6✔
90
                ],
6✔
91
            ]);
6✔
92
            $response = $this->_webSocket->sendRequest($request, function (ApiResponse $response) {
6✔
93
                if (!$response->ok()) {
6✔
94
                    $exception = new ApiException($response);
3✔
95
                    $this->dispatch(new ErrorEvent($exception), self::EVENT_RENEW_ERROR);
3✔
96
                    return;
3✔
97
                }
98
                $this->setSubscription($response->body());
3✔
99
                $this->dispatch(new SuccessEvent($response), self::EVENT_RENEW_SUCCESS);
3✔
100
            });
6✔
101
        } catch (Exception $e) {
×
102
            $this->reset();
×
103
            throw $e;
×
104
        }
105
    }
106

107
    /**
108
     * @param array $options
109
     *
110
     * @throws Exception
111
     *
112
     * @return ApiResponse|$this
113
     */
114
    public function register(array $options = [])
115
    {
116
        $this->_webSocket->removeListener(WebSocket::EVENT_NOTIFICATION, [$this, 'onNotification']);
6✔
117
        $this->_webSocket->addListener(WebSocket::EVENT_NOTIFICATION, [$this, 'onNotification']);
6✔
118
        if ($this->alive()) {
6✔
119
            return $this->renew($options);
6✔
120
        } else {
121
            return $this->subscribe($options);
6✔
122
        }
123
    }
124

125
    protected function onNotification($event)
126
    {
127
        $this->dispatch($event, self::EVENT_NOTIFICATION);
3✔
128
    }
129

130
    public function reset() {
131
        $this->_subscription = null;
3✔
132
    }
133

134
    /**
135
     * @return bool
136
     */
137
    public function alive()
138
    {
139
        return $this->subscribed();
12✔
140
    }
141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc