-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathchat_ws_server.php
101 lines (80 loc) · 3.13 KB
/
chat_ws_server.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Ratchet\RFC6455\Messaging\Message;
use React\EventLoop\Factory;
use React\Http\Message\Response;
use React\Http\Server;
use React\Stream\ThroughStream;
use Voryx\WebSocketMiddleware\WebSocketConnection;
use Voryx\WebSocketMiddleware\WebSocketMiddleware;
require __DIR__ . '/../vendor/autoload.php';
$loop = Factory::create();
$frontend = file_get_contents(__DIR__ . '/test.html');
$uri = '127.0.0.1:4321';
$broadcast = new ThroughStream();
$ws = new WebSocketMiddleware(['/ws'], function (WebSocketConnection $conn, ServerRequestInterface $request, ResponseInterface $response) use ($broadcast, $loop) {
static $user = 0;
// do not send on the connection before the react http server has a chance to start listening
// on the streams
$loop->addTimer(0, function () use ($conn, $user, $broadcast) {
$broadcast->write('user ' . $user . ' connected');
$conn->send('Welcome. You are user ' . $user);
});
$broadcastHandler = function ($data) use ($conn) {
$conn->send($data);
};
$broadcast->on('data', $broadcastHandler);
$conn->on('message', function (Message $message) use ($broadcast, $conn, $user) {
$broadcast->write('user ' . $user . ': ' . $message->getPayload());
});
$conn->on('error', function (Throwable $e) use ($broadcast, $user, $broadcastHandler) {
$broadcast->removeListener('data', $broadcastHandler);
$broadcast->write('user ' . $user . ' left because of error: ' . $e->getMessage());
});
$conn->on('close', function () use ($broadcast, $user, $broadcastHandler) {
$broadcast->removeListener('data', $broadcastHandler);
$broadcast->write('user ' . $user . ' closed their connection');
});
$user++;
});
$server = new Server(
$loop,
function (ServerRequestInterface $request, callable $next) use ($broadcast) {
// lets let the people chatting see what requests are happening too.
$broadcast->write('<i>Request: ' . $request->getUri()->getPath() . '</i>');
return $next($request);
},
$ws,
function (ServerRequestInterface $request, callable $next) {
$request = $request->withHeader('Request-Time', time());
return $next($request);
},
function (ServerRequestInterface $request) use ($frontend) {
return new Response(200, [], $frontend);
},
);
$server->listen(new \React\Socket\Server('127.0.0.1:4321', $loop));
$server->on('error', static function (Throwable $e) {
echo $e;
});
openWebPage($loop, 'http://' . $uri);
$loop->run();
function openWebPage($loop, $url)
{
$os = strtolower(php_uname(PHP_OS));
if (strpos($os, 'darwin') !== false) {
$open = 'open';
} elseif (strpos($os, 'linux') !== false) {
$open = 'xdg-open';
} else {
echo "Can't open your browser, you'll have to manually navigate to {$url}", PHP_EOL;
return;
}
$process = new React\ChildProcess\Process("{$open} {$url}");
try {
$process->start($loop);
} catch (Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
}