Completed
Push — master ( 84c8b4...76453f )
by Julien
05:23
created

Server::run()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 20
rs 9.4285
cc 3
eloc 10
nc 4
nop 0
1
<?php
2
3
namespace Eole\Sandstone\Websocket;
4
5
use Psr\Log\LoggerAwareTrait;
6
use ZMQ;
7
use React\ZMQ\Context;
8
use React\EventLoop\LoopInterface;
9
use React\EventLoop\Factory;
10
use React\Socket\Server as ReactSocketServer;
11
use Ratchet\Server\IoServer;
12
use Ratchet\Http\HttpServer;
13
use Ratchet\Websocket\WsServer;
14
use Ratchet\Wamp\ServerProtocol;
15
use Eole\Sandstone\Logger\EchoLogger;
16
use Eole\Sandstone\Application as SandstoneApplication;
17
use Eole\Sandstone\Websocket\Application as WebsocketApplication;
18
19
class Server
20
{
21
    use LoggerAwareTrait;
22
23
    /**
24
     * @var SandstoneApplication
25
     */
26
    private $sandstoneApplication;
27
28
    /**
29
     * @var LoopInterface
30
     */
31
    private $loop;
32
33
    /**
34
     * @param SandstoneApplication $sandstoneApplication
35
     */
36
    public function __construct(SandstoneApplication $sandstoneApplication)
37
    {
38
        $this->sandstoneApplication = $sandstoneApplication;
39
        $this->loop = Factory::create();
40
41
        $this->setLogger(new EchoLogger());
42
    }
43
44
    /**
45
     * Init websocket server and push server if enabled.
46
     */
47
    private function initWebsocketServer()
48
    {
49
        $websocketBind = $this->sandstoneApplication['sandstone.websocket.server']['bind'];
50
        $websocketPort = $this->sandstoneApplication['sandstone.websocket.server']['port'];
51
52
        $socket = new ReactSocketServer($this->loop);
53
        $socket->listen($websocketPort, $websocketBind);
54
55
        new IoServer(
56
            new HttpServer(
57
                new WsServer(
58
                    new ServerProtocol(
59
                        new WebsocketApplication(
60
                            $this->sandstoneApplication
61
                        )
62
                    )
63
                )
64
            ),
65
            $socket
66
        );
67
    }
68
69
    /**
70
     * Init push server and redispatch events from push server to application stack.
71
     */
72
    private function initPushServer()
73
    {
74
        $pushBind = $this->sandstoneApplication['sandstone.push.server']['bind'];
75
        $pushPort = $this->sandstoneApplication['sandstone.push.server']['port'];
76
77
        $context = new Context($this->loop);
78
        $pushServer = $context->getSocket(ZMQ::SOCKET_PULL);
79
80
        $pushServer->bind("tcp://$pushBind:$pushPort");
81
82
        $pushServer->on('message', function ($message) {
83
            $data = $this->sandstoneApplication['sandstone.push.event_serializer']->deserializeEvent($message);
84
85
            $this->logger->info('Push message event', ['event' => $data['name']]);
86
87
            $this->sandstoneApplication['dispatcher']->dispatch($data['name'], $data['event']);
88
        });
89
    }
90
91
    /**
92
     * Run websocket server.
93
     */
94
    public function run()
95
    {
96
        $this->logger->info('Initialization...');
97
98
        $this->initWebsocketServer();
99
100
        if ($this->sandstoneApplication->isPushServerEnabled()) {
101
            $this->initPushServer();
102
        }
103
104
        $this->sandstoneApplication->boot();
105
106
        $this->logger->info('Bind websocket server', $this->sandstoneApplication['sandstone.websocket.server']);
107
108
        if ($this->sandstoneApplication->isPushServerEnabled()) {
109
            $this->logger->info('Bind push server', $this->sandstoneApplication['sandstone.push.server']);
110
        }
111
112
        $this->loop->run();
113
    }
114
}
115