Completed
Pull Request — master (#100)
by Maxime
01:49
created

WebSocketClient   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 8
dl 0
loc 119
ccs 0
cts 60
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A start() 0 16 3
A setConfig() 0 10 1
A getConnectorFactory() 0 19 4
A getLoop() 0 8 2
A getMessageProcessor() 0 8 2
1
<?php
2
3
/**
4
 * This file is a part of Woketo package.
5
 *
6
 * (c) Nekland <[email protected]>
7
 *
8
 * For the full license, take a look to the LICENSE file
9
 * on the root directory of this project
10
 */
11
12
namespace Nekland\Woketo\Client;
13
14
use Nekland\Woketo\Http\Url;
15
use Nekland\Woketo\Message\MessageHandlerInterface;
16
use Nekland\Woketo\Rfc6455\MessageProcessor;
17
use React\EventLoop\Factory as LoopFactory;
18
use React\EventLoop\LoopInterface;
19
20
class WebSocketClient
21
{
22
    /**
23
     * @var Url
24
     */
25
    private $url;
26
27
    /**
28
     * @var array
29
     */
30
    private $config;
31
32
    /**
33
     * @var Connection
34
     */
35
    private $connection;
36
37
    /**
38
     * @var ConnectorFactoryInterface
39
     */
40
    private $connectorFactory;
41
42
    /**
43
     * @var LoopInterface
44
     */
45
    private $loop;
46
47
    public function __construct(string $url, array $config = [], ConnectorFactoryInterface $connectorFactory = null)
48
    {
49
        $this->url = new Url($url);
50
        $this->connectorFactory = $connectorFactory;
51
        $this->setConfig($config);
52
    }
53
54
    /**
55
     * @param MessageHandlerInterface $handler
56
     * @throws \Exception
57
     */
58
    public function start(MessageHandlerInterface $handler)
59
    {
60
        if ($this->config['prod'] && \extension_loaded('xdebug')) {
61
            throw new \Exception('xdebug is enabled, it\'s a performance issue. Disable that extension or specify "prod" option to false.');
62
        }
63
64
        $this->connection = new Connection(
65
            $this->url,
66
            $this->getConnectorFactory()->createConnector()->connect($this->url->getHost() . ':' . $this->url->getPort()),
67
            $this->getMessageProcessor(),
68
            $handler,
69
            $this->loop
70
        );
71
72
        $this->loop->run();
73
    }
74
75
    /**
76
     * @param array $config
77
     * @return self
78
     */
79
    public function setConfig(array $config = [])
80
    {
81
        $this->config = array_merge([
82
            'prod' => true,
83
            'ssl' => [],
84
            'dns' => null,
85
        ], $config);
86
87
        return $this;
88
    }
89
90
    /**
91
     * Creates a connector factory with the given configuration if none given in the constructor.
92
     *
93
     * @return ConnectorFactoryInterface
94
     */
95
    private function getConnectorFactory() : ConnectorFactoryInterface
96
    {
97
        if ($this->connectorFactory !== null) {
98
            return $this->connectorFactory;
99
        }
100
        $this->connectorFactory = new ConnectorFactory();
101
        $this->connectorFactory->setLoop($this->getLoop());
102
        $this->connectorFactory->setSslOptions($this->config['ssl']);
103
104
        $this->connectorFactory->enableDns();
105
        if (null !== $this->config['dns']) {
106
            $this->connectorFactory->setDnsServer($this->config['dns']);
107
        }
108
        if ($this->url->isSecured()) {
109
            $this->connectorFactory->enableSsl();
110
        }
111
112
        return $this->connectorFactory;
113
    }
114
115
    /**
116
     * @return LoopInterface
117
     */
118
    private function getLoop() : LoopInterface
119
    {
120
        if (null !== $this->loop) {
121
            return $this->loop;
122
        }
123
124
        return $this->loop = LoopFactory::create();
125
    }
126
127
    /**
128
     * @return MessageProcessor
129
     */
130
    private function getMessageProcessor(): MessageProcessor
131
    {
132
        if (!empty($this->messageProcessor)) {
133
            return $this->messageProcessor;
0 ignored issues
show
Bug introduced by
The property messageProcessor does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
134
        }
135
136
        return $this->messageProcessor = new MessageProcessor();
137
    }
138
}
139