-
Notifications
You must be signed in to change notification settings - Fork 6
/
server_async.php
126 lines (116 loc) · 3.86 KB
/
server_async.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
class WebRTC
{
const WEBROOT = __DIR__ . '/web';
public static $server = null;
public static $subject2fd = [];
public static $fd2subject = [];
function onClose(Swoole\Server $server, int $fd, int $reactorId)
{
echo "server: $fd closed\n";
if (isset(self::$fd2subject[$fd])) {
$subject = self::$fd2subject[$fd];
unset(self::$subject2fd[$subject][$fd]);
}
}
function onOpen(Swoole\WebSocket\Server $server, $request)
{
echo "server: handshake success with fd{$request->fd}\n";
}
function onMessage(Swoole\WebSocket\Server $server, $frame)
{
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$fd = $frame->fd;
$data = json_decode($frame->data, true);
switch ($data['cmd']) {
case 'subscribe':
$subject = $data['subject'];
self::$subject2fd[$subject][$fd] = $fd;//每个房间可能有多个连接
self::$fd2subject[$fd] = $subject;//一个连接只能对应一个房间
break;
case 'publish':
$this->publish($data, $fd);
break;
}
}
function publish($data, $current_fd)
{
$subject = $data['subject'];
$event = $data['event'];
$data = $data['data'];
if (empty(self::$subject2fd[$subject])) {
return;
}
foreach (self::$subject2fd[$subject] as $_fd) {
if ($_fd == $current_fd) {
continue;
}
self::$server->push($_fd,
json_encode(
array(
'cmd' => 'publish',
'event' => $event,
'data' => $data
)
)
);
}
}
function onRequest(Swoole\Http\Request $request, Swoole\Http\Response $response)
{
$path = $request->server['request_uri'];
if ($path == "/") {
$response->sendfile(self::WEBROOT . '/index.html');
} else {
$file = realpath(self::WEBROOT . $path);
if (false === $file) {
$response->status(404);
$response->end('<h3>404 Not Found</h3>');
return;
}
if (\pathinfo($file, PATHINFO_EXTENSION) === 'php') {
$response->end($this->get_php_file($file));
return;
}
if (isset($req->header['if-modified-since']) and !empty($if_modified_since = $req->header['if-modified-since'])) {
$info = \stat($file);
$modified_time = $info ? \date(
'D, d M Y H:i:s',
$info['mtime']
) . ' ' . \date_default_timezone_get() : '';
if ($modified_time === $if_modified_since) {
$response->status(304);
$response->end();
return;
}
}
$response->sendfile($file);
}
}
function get_php_file($file)
{
\ob_start();
try {
include $file;
} catch (\Exception $e) {
echo $e;
}
return \ob_get_clean();
}
function run()
{
$server = new Swoole\WebSocket\Server("0.0.0.0", 9509, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$server->set([
'ssl_key_file' => __DIR__ . '/ssl/ssl.key',
'ssl_cert_file' => __DIR__ . '/ssl/ssl.crt',
]);
$server->on('open', [$this, "onOpen"]);
$server->on('close', [$this, "onClose"]);
$server->on('message', [$this, "onMessage"]);
$server->on('request', [$this, "onRequest"]);
self::$server = $server;
$server->start();
}
}
$w = new WebRTC();
$w->run();