4.理解信号
41)查看liinux信号 kill -l
信号列表及意义:https://wiki.swoole.com/#/other/signal?id=linux-信号列表
使用 kill 信号 主进程PID 如下,kill -10 11830 ,重启了workers
42)信号函数
pcntl_signal 安装信号https://php.golaravel.com/function.pcntl-signa.html
posix_kill 绑定信号https://php.golaravel.com/function.posix-kill.html
pcntl_signal_dispatch 发送信号https://php.golaravel.com/function.pcntl-signa-dispatch.html
43)程序设置信号的流程
44)客户端Xshell等kill命令信号的流程
45)理解信号函数
小试牛刀
iostarjhy\test\signal\signal.php
<?php
function sig_handler($sig){
var_dump($sig);
echo "信号操作\n";
}
//绑定信号及触发方法(处理方法)
pcntl_signal(SIGIO,"sig_handler");
//SIGIO :描述符上可以进行 I/O 操作
//绑定进程和信号
posix_kill(posix_getpid(),SIGIO);
echo "kl\n";
//分发
pcntl_signal_dispatch();
运行
<?php
namespace IoStarJhy\Signal;
use IoStarJhy\WorkerBase;
class Worker extends WorkerBase {
public function accept()
{
//建立并挂起连接,可接受多次信息(而不是一次就关闭服务)
while(true){
//监听是否存在连接
$conn = stream_socket_accept($this->server);
if(!empty($conn)){
//触发建立连接事件
$this->events['connect']($this,$conn);
}
//绑定信号及触发方法(处理方法)
pcntl_signal(SIGIO,$this->sigHandler($conn));
//绑定进程和信号
posix_kill(posix_getpid(),SIGIO);
//分发
pcntl_signal_dispatch();
}
}
public function sigHandler($conn)
{
return function($sig) use($conn){
switch($sig){
case SIGIO;
$this->sendMessage($conn);
break;
}
};
}
public function sendMessage($conn)
{
//接收服务的信息
$data = fread($conn, 65535);
if($data === '' || false === $data){
$this->checkConn($data, $conn);
}else{
$this->events['receive']($this, $conn, $data);
}
}
//检验连接
protected function checkConn($buffer,$conn){
if(strlen($buffer) === 0){
if(! \get_resource_type($conn) == "Unknown"){
//断开连接
$this->close($conn);
}
call_user_func($this->events['close'],$this,$conn);
unset($this->sockets[(int) $conn]);
}
}
}
<?php
require_once __DIR__."/../../vendor/autoload.php";
use IoStarJhy\Signal\Worker;
$server = new Worker('0.0.0.0',9500);
$server->on('connect',function($server,$client){
dd($client,"客户端建立连接成功");
});
$server->on('receive',function(Worker $server,$client,$data){
dd($data,'处理客户端的数据');
$server->send($client,'hello client');
//$server->close($client);
});
$server->on('close',function(Worker $server,$client){
dd($client,'断开连接');
//$server->close($client);
});
$server->start();
<?php
require_once __DIR__ . "/../../vendor/autoload.php";
//连接服务端
$fp = stream_socket_client("tcp://192.168.204.168:9500");
fwrite($fp, "hello server1");
dd(fread($fp, 65535));
至此,信号模型已实现通信了
说明:信号模型主要用于框架中服务的重启,重加载及不同进程间的通讯,而不是用于写模型的。
附:
问题:为什么阻塞模型不能进行两次通信?
receive后,进行下一轮,stream_socket_accept去监听新的连接了,上一个连接再发信息也没用了
完
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!