胜,不妄喜;败,不遑馁;胸有激雷而面如平湖者,可拜上将军。 —— 春秋战国·孙武 《孙子兵法》
一、基础
Swoole就是披着PHP外衣的C程序,类似于Java等语言里面的高阶功能,如持久连接、异步通信、Websocket、多线程等。
Swoole是由C语言开发的PHP扩展类,由于有着C语言的优势,Swoole在内存管理、数据结构、通信协议解析等方面优势明显。它是一个面向生产环境的PHP异步网络通信引擎,使PHP开发人员可以编写高性能的异步并发TCP、UDP、Unix Socket、HTTP、WebSocket等服务。Swoole可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。
二、实战
安装
- 下载源码包至
/usr/local/src
目录下 - 解压
sudo tar -zxvf swoole-4.4.3.tgz
- 切换目录
cd swoole-4.4.3
- 运行
sudo /usr/local/php/7.3/bin/phpize
命令,生成configure可执行文件 - 运行配置
sudo ./configure --with-php-config=/usr/local/php/7.3/bin/php-config
- 安装扩展
sudo make && sudo make install
- 报错:
configure: error: C compiler cannot create executables
,解决sudo xcodebuild -license accept
- 报错:
- 修改php.ini文件,增加
extension=/path/swoole.so
- 重启php-fpm
- 查看是否安装成功
php7.3 -m
,显示swoole则成功
- 下载源码包至
方法列表
/your_path/swoole-4.4.3/ext-src/stubs/php_swoole_server.stub.php
1 | <?php |
实战一:简易聊天室(面向过程)
- 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<?php
use Swoole\WebSocket\Server;
// old version, unsupported
// $ws_server = new swoole_websocket_server('192.168.1.169', 9502);
$ws_server = new Server("0.0.0.0", 9501, SWOOLE_BASE);
$ws_server->set([
'daemonize' => true
]);
$ws_server->on('open', function ($ws, $request) {
// file_put_contents( __DIR__ .'/log.txt' , $request->fd);
$ws->push($request->fd, "From Server!\n");
});
$ws_server->on('message', function ($ws, $frame) {
pushMessage($ws, $frame);
});
$ws_server->on('close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});
$ws_server->start();
function pushMessage($ws, $frame){
// $data = $frame->data;
// $msg = file_get_contents( __DIR__ .'/log.txt');
// for ($i=1; $i<= $msg ; $i++) {
// $ws->push($fd, $frame->fd . ':' . $data);
// }
foreach ($ws->connections as $fd) {
$ws->push($fd, $frame->fd . ':' . $frame->data);
}
}- client.html
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<html>
<head>
<title></title>
<meta charset="UTF-8">
<script type="text/javascript">
if(window.WebSocket){
var webSocket = new WebSocket("ws://localhost:9501");
webSocket.onopen = function (event) {
webSocket.send("From Client!");
};
webSocket.onmessage = function (event) {
var content = document.getElementById('content');
content.innerHTML = content.innerHTML.concat(
'<p style="margin-left:20px;height:20px;line-height:20px;">uid:'+event.data+'</p>'
);
}
var sendMessage = function(){
var data = document.getElementById('message').value;
webSocket.send(data);
}
}else{
console.log("您的浏览器不支持WebSocket");
}
</script>
</head>
<body>
<div style="width:600px;margin:0 auto;border:1px solid #ccc;">
<div id="content" style="overflow-y:auto;height:300px;"></div>
<hr/>
<div style="height:40px">
<input type="text" id="message" style="margin-left:10px;height:25px;width:450px;">
<button onclick="sendMessage()" style="height:28px;width:75px;">发送</button>
</div>
</div>
</body>
</html>实战二:简易聊天室(面向对象)
- 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<?php
use Swoole\WebSocket\Server;
class Chat
{
const HOST = '0.0.0.0';
const PART = 9052;
private $server = null;
public function __construct() {
// old version, unsupported
// $this->server = new swoole_websocket_server(self::HOST, self::PART);
$this->server = new Server("0.0.0.0", 9502, SWOOLE_BASE);
// $ref = new ReflectionClass($this->server);
// $data =$ref->getMethods();
// file_put_contents("a.json", json_encode($data));
// $data = $ref->getProperties();
// file_put_contents("b.json", json_encode($data));
$this->server->on('open', [$this, 'onOpen']);
$this->server->on('message', [$this, 'onMessage']);
$this->server->on('close', [$this, 'onClose']);
$this->server->start();
}
public function onOpen($server, $request) {
print_r($server->connection_info($request->fd));
echo $request->fd . '连接了' . PHP_EOL;//打印到我们终端
}
public function onMessage($server, $frame) {
echo $frame->fd . '来了,说:' . $frame->data . PHP_EOL;
foreach ($server->connections as $fd) {
$server->push($fd, json_encode(['no' => $frame->fd, 'msg' => $frame->data]));
}
echo "当前服务器共有".count($server->connections). "个连接\n";
}
public function onClose($server, $fd) {
echo $fd . '走了' . PHP_EOL;//打印到我们终端
}
}
$obj = new Chat();- client.html
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<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>聊天室</title>
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<textarea class="log" style="width: 300px; height: 300px;">
===聊天室===
</textarea><br/>
<input type="button" value="连接" onClick="connect()">
<input type="button" value="断开" onClick="disconnect()">
<input type="input" id="text">
<input type="button" value="发送" onClick="send()">
<script>
function connect() {
var url = 'ws://localhost:9502';
socket = new WebSocket(url);
socket.onopen = function () {
log1('连接成功')
}
socket.onmessage = function (msg) {
log(msg.data);
}
socket.onclose = function () {
log1('断开连接')
}
}
function disconnect() {
socket.close();
socket = null;
}
function log1(var1) {
$('.log').append(var1 + '\r\n');
}
function log(var1) {
var v = $.parseJSON(var1)
$('.log').append('uid:'+v['no']+',msg:'+v['msg']+ '\r\n');
}
function send() {
// var json = $('#text').val();
var json = JSON.stringify({
'type': 'php',
'msg': $('#text').val()
})
console.log(json)
socket.send(json);
}
</script>
</body>
</html>