Completed
Push — master ( 417ea8...dd48e2 )
by Maik
01:38
created

ServerSocket   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 66.67%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 5
dl 0
loc 80
ccs 4
cts 6
cp 0.6667
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
B serve() 0 28 4
A bind() 0 7 2
A listen() 0 7 2
1
<?php
2
3
/**
4
 * This file is part of the PHP Generics package.
5
 *
6
 * @package Generics
7
 */
8
namespace Generics\Socket;
9
10
/**
11
 * This class provides a basic client socket implementation
12
 *
13
 * @author Maik Greubel <[email protected]>
14
 */
15
class ServerSocket extends Socket
16
{
17
18
    /**
19
     * Create a new server socket
20
     *
21
     * @param Endpoint $endpoint
22
     *            The endpoint to use
23
     *            
24
     * @throws SocketException In case of creation of socket has failed or socket options could not be set.
25
     */
26 1
    public function __construct(Endpoint $endpoint)
27
    {
28 1
        parent::__construct($endpoint);
29 1
        if (! @socket_set_option($this->handle, SOL_SOCKET, SO_REUSEADDR, 1)) {
30
            $code = socket_last_error($this->handle);
31
            throw new SocketException(socket_strerror($code), array(), $code);
32
        }
33 1
    }
34
35
    /**
36
     * Creates a service at the given endpoint
37
     *
38
     * @throws SocketException in case of it is not possible to serve due to binding or listening error
39
     */
40
    public function serve(ServiceCallback $callback)
41
    {
42
        $this->bind();
43
        
44
        $this->listen();
45
        
46
        $runOn = true;
47
        
48
        while ($runOn) {
49
            $clientHandle = @socket_accept($this->handle);
50
            
51
            if (! is_resource($clientHandle)) {
52
                $code = socket_last_error($this->handle);
53
                throw new SocketException(socket_strerror($code), array(), $code);
54
            }
55
            
56
            $address = null;
57
            $port = 0;
58
            if (! @socket_getpeername($clientHandle, $address, $port)) {
59
                $code = socket_last_error($clientHandle);
60
                throw new SocketException(socket_strerror($code), array(), $code);
61
            }
62
            
63
            $client = new ClientSocket(new Endpoint($address, $port), $clientHandle);
64
            
65
            $runOn = boolval($callback->callback($client));
66
        }
67
    }
68
69
    /**
70
     * Bind the server socket to the given endpoint
71
     *
72
     * @throws SocketException in case of binding has failed
73
     */
74
    private function bind()
75
    {
76
        if (! @socket_bind($this->handle, $this->endpoint->getAddress(), $this->endpoint->getPort())) {
77
            $code = socket_last_error($this->handle);
78
            throw new SocketException(socket_strerror($code), array(), $code);
79
        }
80
    }
81
82
    /**
83
     * Listen to the binded socket endpoint
84
     *
85
     * @throws SocketException in case of listening is not possible
86
     */
87
    private function listen()
88
    {
89
        if (! @socket_listen($this->handle, 5)) {
90
            $code = socket_last_error($this->handle);
91
            throw new SocketException(socket_strerror($code), array(), $code);
92
        }
93
    }
94
}
95