开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情
1.swoole启动关闭方案
1.swoole如何在后台运行
(1)nohup php server.php & 或者 screen php server.php
(2)设置daemonize => 1时,程序将转入后台作为守护进程运行。长时间运行的服务器端程序必须启用此项
- 启用守护进程后,标准输入和输出会被重定向到
log_file - 如果未设置
log_file,将重定向到/dev/null,所有打印屏幕的信息都会被丢弃
2.手动关闭swoole
# 先查看端口对应的进程 id
netstat -tunlp|grep 9501
### 结果 tcp 0 0 0.0.0.0:9400 0.0.0.0:* LISTEN 2750/php
# 再 kill 进程 id 就完事了
kill -9 2750
# 查看进程信息 (当然在 kill 之前查看)
ps -ef|grep 2750
2.swoole服务端主动推送消息
<?php
//创建WebSocket Server对象,监听0.0.0.0:9502端口
$ws = new Swoole\WebSocket\Server('0.0.0.0', 9503);
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
$fd=$request->fd;
var_dump($request->fd, $request->server);
$ws->push($request->fd, "hello, welcome\n");
});
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
//echo "Message: {$frame->data}\n";
$ws->push($frame->fd, "服务端返回:{$frame->data}");
});
//第一种方式:通过curl调用swoole.xian008.com:9501(客户端websocket连接地址)
$ws->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
global $ws;//调用外部的server
//$server->connections 遍历所有websocket连接用户的fd,给所有用户推送
foreach ($ws->connections as $fd) {
// 需要先判断是否是正确的websocket连接,否则有可能会push失败
if ($ws->isEstablished($fd)) {
$ws->push($fd, $request->post['message']);
}
}
});
第二种方式:通过redis订阅来实现
$process = new Swoole\Process(function ($process)use($ws) {
echo 'process';
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
$redis->auth('xiaocinao');
$redis->subscribe(['name'],function ($redis,$channel,$msg)use($ws){
$ws->push(1,$msg);
});
});
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});
$ws->addProcess($process);
$ws->start();
3.创建websocket--systemctl自定义启动服务
在/lib/systemd/system/目录或者/etc/systemd/system/目录下创建service结尾的文件如swoole.service文件
[Unit]
Description=swoole websocket
[Service]
Type=simple
#EnvironmentFile=/etc/systemd/test.conf
ExecStart=/usr/bin/php /home/swoole/extend/lib/Swoole.php
ExecReload=/bin/kill --USR1 $MAINPID
ExecStop=/bin/kill -SIGTERM $MAINPID
[Install]
WantedBy=multi-user.target
$ MAINPID是服务的systemd变量,它指向主应用程序的PID。
4.创建php脚本来启动关闭websocket服务
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2020/11/24
* Time: 17:26
*/
//exec可以把执行的结果全部返回到$output函数里(数组),$status是执行的状态 0为成功 1为失败
$order=$argv[1];
$sh2='/usr/bin/php /home/swoole/extend/lib/Swoole.php';
switch ($order){
case 'start':
exec($sh2,$res,$rc);
if($rc==0){
echo 'success';
}
break;
case 'stop':
$pid=swoole();
\Swoole\Process::kill($pid, $signo = SIGTERM);
echo 'stop';
break;
case 'restart':
$pid=swoole();
\Swoole\Process::kill($pid, SIGUSR1);
echo 'restart';
break;
}
function swoole(){
$sh = 'pgrep -f swoole_master';
exec($sh,$res,$rc);
$pid=$res[0];
return $pid;
}
5.进程、线程、协程
进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程也由操作系统调度。
协程和线程一样共享堆,不共享栈,协程由程序员在代码里调度。(援引网络博文)
6.进程/线程结构图