Completed
Push — master ( d1b7ac...fe3773 )
by Christopher
02:05
created

ZeroMqServer::tick()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
ccs 0
cts 8
cp 0
rs 9.4286
cc 3
eloc 7
nc 3
nop 0
crap 12
1
<?php
2
3
namespace AsyncPHP\Remit\Server;
4
5
use AsyncPHP\Remit\Event;
6
use AsyncPHP\Remit\Event\InMemoryEvent;
7
use AsyncPHP\Remit\Location;
8
use AsyncPHP\Remit\Server;
9
use Closure;
10
use ZMQ;
11
use ZMQContext;
12
use ZMQSocket;
13
14
final class ZeroMqServer implements Server
15
{
16
    /**
17
     * @var Location
18
     */
19
    private $location;
20
21
    /**
22
     * @var ZMQSocket
23
     */
24
    private $socket;
25
26
    /**
27
     * @var array
28
     */
29
    private $listeners = [];
30
31
    /**
32
     * @param Location $location
33
     */
34 2
    public function __construct(Location $location)
35
    {
36 2
        $this->location = $location;
37 2
    }
38
39
    /**
40
     * @inheritdoc
41
     *
42
     * @param string $name
43
     * @param Closure $closure
44
     *
45
     * @return $this
46
     */
47 1
    public function addListener($name, Closure $closure)
48
    {
49 1
        if (empty($this->listeners[$name])) {
50 1
            $hash = spl_object_hash($closure);
51
52 1
            $this->listeners[$name][$hash] = $closure;
53
        }
54
55 1
        return $this;
56
    }
57
58
    /**
59
     * @inheritdoc
60
     *
61
     * @param string $name
62
     * @param Closure $closure
63
     */
64
    public function removeListener($name, Closure $closure)
65
    {
66
        $hash = spl_object_hash($closure);
67
68
        if (isset($this->listeners[$name]) && isset($this->listeners[$name][$hash])) {
69
            unset($this->listeners[$name][$hash]);
70
        }
71
72
        return $this;
73
    }
74
75
    /**
76
     * @inheritdoc
77
     */
78
    public function tick()
79
    {
80
        $socket = $this->getSocket();
81
82
        if (!($event = $socket->recv(ZMQ::MODE_DONTWAIT))) {
83
            return;
84
        }
85
86
        $event = @unserialize($event);
87
88
        if ($event instanceof Event) {
89
            $this->dispatchEvent($event);
90
        }
91
    }
92
93
    /**
94
     * @return ZMQSocket
95
     */
96 View Code Duplication
    private function getSocket()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        if ($this->socket === null) {
99
            $context = new ZMQContext();
100
101
            $host = $this->location->getHost();
102
            $port = $this->location->getPort();
103
104
            $this->socket = new ZMQSocket($context, ZMQ::SOCKET_PULL, spl_object_hash($this));
105
            $this->socket->bind("tcp://{$host}:$port");
106
        }
107
108
        return $this->socket;
109
    }
110
111
    /**
112
     * @param Event $event
113
     *
114
     * @return $this
115
     */
116
    private function dispatchEvent(Event $event)
117
    {
118
        $name = $event->getName();
119
120
        if (isset($this->listeners[$name])) {
121
            foreach ($this->listeners[$name] as $closure) {
122
                call_user_func_array($closure, $event->getParameters());
123
            }
124
        }
125
126
        return $this;
127
    }
128
129
    /**
130
     * @inheritdoc
131
     *
132
     * @param string $name
133
     * @param array $parameters
134
     *
135
     * @return $this
136
     */
137
    public function emit($name, array $parameters = [])
138
    {
139
        return $this->dispatchEvent(
140
            new InMemoryEvent($name, $parameters)
141
        );
142
    }
143
144
    /**
145
     * @inheritdoc
146
     *
147
     * @return string
148
     */
149 1
    public function serialize()
150
    {
151 1
        return serialize($this->location);
152
    }
153
154
    /**
155
     * @inheritdoc
156
     *
157
     * @param string $serialized
158
     */
159 1
    public function unserialize($serialized)
160
    {
161 1
        $this->location = unserialize($serialized);
162 1
    }
163
164
    /**
165
     * @return Location
166
     */
167
    public function getLocation()
168
    {
169
        return $this->location;
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175 1 View Code Duplication
    public function disconnect()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
176
    {
177 1
        if ($this->socket) {
178
            try {
179
                $host = $this->location->getHost();
180
                $port = $this->location->getPort();
181
182
                $this->socket->disconnect("tcp://{$host}:{$port}");
183
            } catch (Exception $exception) {
0 ignored issues
show
Bug introduced by
The class AsyncPHP\Remit\Server\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
184
                // TODO: find an elegant way to deal with this
185
            }
186
        }
187 1
    }
188
189 1
    public function __destruct()
190
    {
191 1
        $this->disconnect();
192 1
    }
193
}
194