Server::initWebsocketServer()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 11
nc 1
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("$websocketBind:$websocketPort", $this->loop);
53
54
        new IoServer(
55
            new HttpServer(
56
                new WsServer(
57
                    new ServerProtocol(
58
                        new WebsocketApplication(
59
                            $this->sandstoneApplication
60
                        )
61
                    )
62
                )
63
            ),
64
            $socket
65
        );
66
    }
67
68
    /**
69
     * Init push server and redispatch events from push server to application stack.
70
     */
71
    private function initPushServer()
72
    {
73
        $pushBind = $this->sandstoneApplication['sandstone.push.server']['bind'];
74
        $pushPort = $this->sandstoneApplication['sandstone.push.server']['port'];
75
76
        $context = new Context($this->loop);
77
        $pushServer = $context->getSocket(ZMQ::SOCKET_PULL);
78
79
        $pushServer->bind("tcp://$pushBind:$pushPort");
80
81
        $pushServer->on('message', function ($message) {
82
            $data = $this->sandstoneApplication['sandstone.push.event_serializer']->deserializeEvent($message);
83
84
            $this->logger->info('Push message event', ['event' => $data['name']]);
85
86
            $this->sandstoneApplication['dispatcher']->dispatch($data['name'], $data['event']);
87
        });
88
    }
89
90
    /**
91
     * Run websocket server.
92
     */
93
    public function run()
94
    {
95
        $this->logger->info('Initialization...');
96
97
        $this->initWebsocketServer();
98
99
        if ($this->sandstoneApplication->isPushEnabled()) {
100
            $this->initPushServer();
101
        }
102
103
        $this->sandstoneApplication->boot();
104
105
        $this->logger->info('Bind websocket server', $this->sandstoneApplication['sandstone.websocket.server']);
106
107
        if ($this->sandstoneApplication->isPushEnabled()) {
108
            $this->logger->info('Bind push server', $this->sandstoneApplication['sandstone.push.server']);
109
        }
110
111
        $this->loop->run();
112
    }
113
}
114