Completed
Pull Request — master (#14)
by Dmitry
08:01
created

StreamConnection   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 93.94%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 3
dl 0
loc 73
ccs 31
cts 33
cp 0.9394
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A open() 0 18 3
A isClosed() 0 4 1
A send() 0 18 4
A __construct() 0 8 3
A close() 0 7 2
1
<?php
2
3
namespace Tarantool\Client\Connection;
4
5
use Tarantool\Client\Exception\ConnectionException;
6
use Tarantool\Client\IProto;
7
use Tarantool\Client\Packer\PackUtils;
8
9
class StreamConnection implements Connection
10
{
11
    const DEFAULT_URI = 'tcp://127.0.0.1:3301';
12
13
    private $uri;
14
15
    private $options = [
16
        'connect_timeout' => 10.0,
17
        'socket_timeout' => 10.0,
18
    ];
19
20
    private $stream;
21
22 44
    public function __construct($uri = null, array $options = null)
23
    {
24 44
        $this->uri = null === $uri ? self::DEFAULT_URI : $uri;
25
26 44
        if ($options) {
27 3
            $this->options = $options + $this->options;
28 3
        }
29 44
    }
30
31 59
    public function open()
32
    {
33 59
        $this->close();
34
35 59
        $stream = @stream_socket_client($this->uri, $errorCode, $errorMessage, (float) $this->options['connect_timeout']);
36 59
        if (false === $stream) {
37 3
            throw new ConnectionException(sprintf('Unable to connect: %s.', $errorMessage));
38
        }
39
40 56
        $this->stream = $stream;
41 56
        stream_set_timeout($this->stream, $this->options['socket_timeout']);
42
43 56
        if (!$greeting = stream_get_contents($this->stream, IProto::GREETING_SIZE)) {
44 4
            throw new ConnectionException('Unable to read greeting.');
45
        }
46
47 53
        return IProto::parseGreeting($greeting);
48
    }
49
50 59
    public function close()
51
    {
52 59
        if ($this->stream) {
53 17
            fclose($this->stream);
54 17
            $this->stream = null;
55 17
        }
56 59
    }
57
58 103
    public function isClosed()
59
    {
60 103
        return null === $this->stream;
61
    }
62
63 102
    public function send($data)
64
    {
65 102
        if (!fwrite($this->stream, $data)) {
66
            throw new ConnectionException('Unable to write request.');
67
        }
68
69 102
        if (!$length = stream_get_contents($this->stream, IProto::LENGTH_SIZE)) {
70 1
            throw new ConnectionException('Unable to read response length.');
71
        }
72
73 101
        $length = PackUtils::unpackLength($length);
74
75 101
        if (!$data = stream_get_contents($this->stream, $length)) {
76
            throw new ConnectionException('Unable to read response.');
77
        }
78
79 101
        return $data;
80
    }
81
}
82