您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
workerman利用reloadable属性实现新增业务代码载入并保持已有客户端连接
发布时间:2021-11-30 22:45:06编辑:雪饮阅读()
reloadable
说明:
bool Worker::$reloadable
设置当前Worker实例是否可以reload,即收到reload信号后是否退出重启。不设置默认为true,收到reload信号后自动重启进程。
有些进程维持着客户端连接,例如Gateway/Worker模型中的gateway进程,当运行reload重新载入业务代码时,却又不想客户端连接断开,则设置gateway进程的reloadable属性为false
首先我们来模拟实现reloadable为false的情况:
web前端进行websocket连接,如用两个浏览器模拟
服务端脚本如:
test.php:
<?php
use Workerman\Connection\TcpConnection;
use Workerman\Lib\Timer;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:8484');
// 设置此实例收到reload信号后是否reload重启
$worker->reloadable = false;
$worker->onWorkerStart = function($worker)
{
// 定时,每1秒一次
Timer::add(1, function()use($worker)
{
var_dump("当前连接数:".count($worker->connections));
// 遍历当前进程所有的客户端连接,发送当前服务器的时间
foreach($worker->connections as $connection)
{
$connect_num=count($worker->connections);
$connection->send("当前连接数:".$connect_num);
$connection->onMessage = function(TcpConnection $connection, $data)
{
$connection->send('receive success');
};
}
});
};
// 运行worker
Worker::runAll();
?>
服务端实例运行效果
[root@izj6c2jeancylo0ppo4vz5z workerman]# php test.php start
Workerman[test.php] start in DEBUG mode
------------------------------------------- WORKERMAN --------------------------------------------
Workerman version:4.0.22 PHP version:7.0.33
-------------------------------------------- WORKERS ---------------------------------------------
proto user worker listen processes status
tcp root none websocket://0.0.0.0:8484 1 [OK]
--------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
Workerman[test.php] reloading
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
另开会话进行reload:
[root@izj6c2jeancylo0ppo4vz5z workerman]# php test.php reload
Workerman[test.php] reload
这里服务端先开,然后两个浏览器就去连接,然后另外开的会话的,于是最终效果就是上面这个服务端实例运行的效果了,可以看到reloadable为false时候有线程对外有socket连接情况下这些连接就不会断开,进程不会重启。
那么接下来咱们去除掉reloadable属性,即默认为true:
接下来的测试由于我回到家里了,上面那个实例是我在公司,而且公司电脑连虚拟机都跑不起来,硬盘太小了,正常使用经常都不够用。。,所以我借助连接我个人的远程服务器完成的。那么现在我下班在家,所以下面的实践我都是在我虚拟机上的。
start.php:
<?php
use Workerman\Connection\TcpConnection;
use Workerman\Lib\Timer;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:8484');
$worker->onWorkerStart = function($worker)
{
// 定时,每1秒一次
Timer::add(1, function()use($worker)
{
var_dump("当前连接数:".count($worker->connections));
// 遍历当前进程所有的客户端连接,发送当前服务器的时间
foreach($worker->connections as $connection)
{
$connect_num=count($worker->connections);
$connection->send("当前连接数:".$connect_num);
$connection->onMessage = function(TcpConnection $connection, $data)
{
$connection->send('receive success');
};
}
});
};
// 运行worker
Worker::runAll();
?>
同样以上面的操作流程模拟,可以看到服务端运行如:
[root@localhost workerman]# php -c /usr/local/php734/lib/php/php.ini start.php start
Workerman[start.php] start in DEBUG mode
------------------------------------------- WORKERMAN --------------------------------------------
Workerman version:4.0.22 PHP version:7.3.4
-------------------------------------------- WORKERS ---------------------------------------------
proto user worker listen processes status
tcp root none websocket://0.0.0.0:8484 1 [OK]
--------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
string(17) "当前连接数:0"
string(17) "当前连接数:0"
string(17) "当前连接数:0"
string(17) "当前连接数:0"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:1"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
string(17) "当前连接数:2"
Workerman[start.php] reloading
string(17) "当前连接数:0"
string(17) "当前连接数:0"
string(17) "当前连接数:0"
string(17) "当前连接数:0"
string(17) "当前连接数:0"
这里可以看到这次reload后进程都重启了,所以当前连接数也就都重置了,前端的连接也都断开了。
如果有兴趣的话,那么前端用的脚本html代码如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://www.w3school.com.cn/jquery/jquery-1.11.1.min.js"></script>
<script type="">
$(document).ready(function(){
var ws = new WebSocket("ws://192.168.43.170:8484");
//申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的url使用ws://开头,另外安全的WebSocket协议使用wss://开头
ws.onopen = function(){
//当WebSocket创建成功时,触发onopen事件
console.log("open");
ws.send("hello"); //将消息发送到服务端
}
ws.onmessage = function(e){
//当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
ws.send("hello");
}
ws.onclose = function(e){
//当客户端收到服务端发送的关闭连接请求时,触发onclose事件
console.log("close");
}
ws.onerror = function(e){
//如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
console.log(error);
}
});
</script>
</head>
<body>
</body>
</html>
关键字词:workerman,reloadable