Server::reply()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * TCP accelerator [server]
4
 * User: moyo
5
 * Date: 2018/7/30
6
 * Time: 12:31 PM
7
 */
8
9
namespace Carno\HRPC\Accel;
10
11
use Carno\HRPC\Accel\Chips\Protocol;
12
use Carno\HRPC\Accel\Chips\Sequence;
13
use Carno\HRPC\Accel\Chips\Specification;
14
use Carno\HRPC\Accel\Contracts\Config;
15
use Carno\HRPC\Accel\Exception\TransportNowClosedException;
16
use Carno\HRPC\Accel\Transport\Reconciled;
17
use Carno\HTTP\Server\Connection;
18
use Carno\Net\Address;
19
use Carno\Net\Contracts\HTTP;
20
use Carno\Net\Events;
21
use Carno\Socket\Contracts\Stream;
22
use Carno\Socket\Options;
23
use Carno\Socket\Powered\Swoole\Server as Socket;
24
use Psr\Http\Message\ResponseInterface as Response;
25
use Swoole\Server as SWServer;
0 ignored issues
show
Bug introduced by
The type Swoole\Server was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use Throwable;
27
28
class Server implements HTTP
29
{
30
    use Protocol, Sequence, Specification;
31
32
    /**
33
     * @var Address
34
     */
35
    private $bind = null;
36
37
    /**
38
     * @var SWServer
39
     */
40
    private $master = null;
41
42
    /**
43
     * @var Events
44
     */
45
    private $events = null;
46
47
    /**
48
     * @var Reconciled
49
     */
50
    private $reconcile = null;
51
52
    /**
53
     * @var int
54
     */
55
    private $ported = 0;
56
57
    /**
58
     * Server constructor.
59
     * @param Address $bind
60
     * @param SWServer $master
61
     * @param Events $events
62
     */
63
    public function __construct(Address $bind, SWServer $master, Events $events)
64
    {
65
        $this->bind = $bind;
66
        $this->master = $master;
67
        $this->events = $events;
68
        $this->reconcile = new Reconciled;
69
    }
70
71
    /**
72
     * @return int
73
     */
74
    public function ported() : int
75
    {
76
        return $this->ported;
77
    }
78
79
    /**
80
     */
81
    public function serve() : void
82
    {
83
        $ported = $this->master->listen($this->bind->host(), $this->bind->port(), SWOOLE_SOCK_TCP);
0 ignored issues
show
Bug introduced by
The constant Carno\HRPC\Accel\SWOOLE_SOCK_TCP was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
84
        if ($ported instanceof SWServer\Port) {
0 ignored issues
show
Bug introduced by
The type Swoole\Server\Port was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
85
            (new Socket)->porting(
86
                $this->master,
87
                $ported,
88
                (new Events)->attach(
89
                    Events\Socket::RECEIVED,
90
                    [$this, 'received']
91
                ),
92
                new Options(Config::SW_PACKAGE, Config::SW_SOCKET, Config::SOCK_SERVER)
93
            );
94
            $this->ported = $ported->port;
95
        }
96
    }
97
98
    /**
99
     */
100
    public function shutdown() : void
101
    {
102
        $this->reconcile->shutdown(new TransportNowClosedException);
103
    }
104
105
    /**
106
     * @param Stream $socket
107
     */
108
    public function received(Stream $socket) : void
109
    {
110
        [$seq, $message] = $this->unpacking($socket->recv());
111
112
        try {
113
            $request = $this->s2request($message);
114
        } catch (Throwable $e) {
115
            $socket->close();
116
            return;
117
        }
118
119
        $this->reconcile->wait($idx = $this->seq())->message()->then(function (string $message) use ($seq, $socket) {
120
            return $socket->write($this->packing($seq, $message));
121
        }, static function () use ($socket) {
122
            return $socket->close();
123
        });
124
125
        $this->events->notify(
126
            Events\HTTP::REQUESTING,
127
            (new Connection)
128
                ->setID($idx)
129
                ->setSEQ($seq)
130
                ->setRequest($request)
131
                ->setLocal($socket->local()->host(), $socket->local()->port())
132
                ->setRemote($socket->remote()->host(), $socket->remote()->port())
133
                ->setServiced($socket->serviced())
134
                ->from($this)
135
        );
136
    }
137
138
    /**
139
     * @param int $conn
140
     * @param Response $response
141
     * @return bool
142
     */
143
    public function reply(int $conn, Response $response) : bool
144
    {
145
        return $this->reconcile->done($conn, $this->response2s($response));
146
    }
147
148
    /**
149
     * @param int $conn
150
     * @return bool
151
     */
152
    public function close(int $conn) : bool
153
    {
154
        return $this->reconcile->fail($conn);
155
    }
156
}
157