Completed
Pull Request — master (#181)
by
unknown
02:29
created

WebSocketHandler::onOpen()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace BeyondCode\LaravelWebSockets\WebSockets;
4
5
use Exception;
6
use Ratchet\ConnectionInterface;
7
use BeyondCode\LaravelWebSockets\Apps\App;
8
use Ratchet\RFC6455\Messaging\MessageInterface;
9
use Ratchet\WebSocket\MessageComponentInterface;
10
use BeyondCode\LaravelWebSockets\QueryParameters;
11
use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
12
use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger;
13
use BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager;
14
use BeyondCode\LaravelWebSockets\WebSockets\Exceptions\UnknownAppKey;
15
use BeyondCode\LaravelWebSockets\WebSockets\Exceptions\WebSocketException;
16
use BeyondCode\LaravelWebSockets\WebSockets\Messages\PusherMessageFactory;
17
use BeyondCode\LaravelWebSockets\WebSockets\Exceptions\ConnectionsOverCapacity;
18
19
class WebSocketHandler implements MessageComponentInterface
20
{
21
    /** @var \BeyondCode\LaravelWebSockets\WebSockets\Channels\ChannelManager */
22
    protected $channelManager;
23
24
    public function __construct(ChannelManager $channelManager)
25
    {
26
        $this->channelManager = $channelManager;
27
    }
28
29
    public function onOpen(ConnectionInterface $connection)
30
    {
31
        $this
32
            ->verifyAppKey($connection)
33
            ->limitConcurrentConnections($connection)
34
            ->generateSocketId($connection)
35
            ->establishConnection($connection);
36
    }
37
38
    public function onMessage(ConnectionInterface $connection, MessageInterface $message)
39
    {
40
        $pusherMessage = PusherMessageFactory::createForMessage($message, $connection, $this->channelManager);
41
42
        $pusherMessage->respond();
43
44
        StatisticsLogger::webSocketMessage($connection);
45
46
        if ($connection->app->clientMessagesEnabled) {
0 ignored issues
show
Bug introduced by
Accessing app on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
47
            $payload = json_decode($message->getPayload());
48
            if (isset($payload->event)
49
                && in_array($payload->event, $connection->app->dispatchEventsForClientMessages)
0 ignored issues
show
Bug introduced by
Accessing app on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
50
            ) {
51
                $this->dispatchClientMessageEvent($payload->event, $payload);
52
            }
53
        }
54
    }
55
56
    public function onClose(ConnectionInterface $connection)
57
    {
58
        $this->channelManager->removeFromAllChannels($connection);
59
60
        DashboardLogger::disconnection($connection);
61
62
        StatisticsLogger::disconnection($connection);
63
    }
64
65
    public function onError(ConnectionInterface $connection, Exception $exception)
66
    {
67
        if ($exception instanceof WebSocketException) {
68
            $connection->send(json_encode(
69
                $exception->getPayload()
70
            ));
71
        }
72
    }
73
74
    protected function verifyAppKey(ConnectionInterface $connection)
75
    {
76
        $appKey = QueryParameters::create($connection->httpRequest)->get('appKey');
0 ignored issues
show
Bug introduced by
Accessing httpRequest on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
77
78
        if (! $app = App::findByKey($appKey)) {
79
            throw new UnknownAppKey($appKey);
80
        }
81
82
        $connection->app = $app;
0 ignored issues
show
Bug introduced by
Accessing app on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
83
84
        return $this;
85
    }
86
87
    protected function limitConcurrentConnections(ConnectionInterface $connection)
88
    {
89
        if (! is_null($capacity = $connection->app->capacity)) {
0 ignored issues
show
Bug introduced by
Accessing app on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
90
            $connectionsCount = $this->channelManager->getConnectionCount($connection->app->id);
0 ignored issues
show
Bug introduced by
Accessing app on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
91
            if ($connectionsCount >= $capacity) {
92
                throw new ConnectionsOverCapacity();
93
            }
94
        }
95
96
        return $this;
97
    }
98
99
    protected function generateSocketId(ConnectionInterface $connection)
100
    {
101
        $socketId = sprintf('%d.%d', random_int(1, 1000000000), random_int(1, 1000000000));
102
103
        $connection->socketId = $socketId;
0 ignored issues
show
Bug introduced by
Accessing socketId on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
104
105
        return $this;
106
    }
107
108
    protected function establishConnection(ConnectionInterface $connection)
109
    {
110
        $connection->send(json_encode([
111
            'event' => 'pusher:connection_established',
112
            'data' => json_encode([
113
                'socket_id' => $connection->socketId,
0 ignored issues
show
Bug introduced by
Accessing socketId on the interface Ratchet\ConnectionInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
114
                'activity_timeout' => 30,
115
            ]),
116
        ]));
117
118
        DashboardLogger::connection($connection);
119
120
        StatisticsLogger::connection($connection);
121
122
        return $this;
123
    }
124
125
    protected function dispatchClientMessageEvent(string $event, $payload)
126
    {
127
        app('events')->dispatch('websockets.'.$event, [$payload]);
128
    }
129
}
130