workerman只管開啟,不管關閉,管殺不管埋,結果因為業(yè)務需求只能無奈轉向swoole。而swoole都可以自由控制:
作為http服務端可以:Swoole\Server->shutdown() 關閉服務,停止監(jiān)聽
作為客戶端可以: Swoole\Coroutine\Client->close()關閉客戶端
多進程,可以 Swoole\Process\Pool->shutdown(): 關閉進程
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:8484');
$worker->onWorkerStart = function(Worker $worker)
{
};
$worker->onMessage = function(TcpConnection $connection, $data)
{
// 當收到特定的消息后如何退出workerman?停止監(jiān)聽端口,執(zhí)行后面的代碼
};
// 運行worker
Worker::runAll();
// 如何退出workerman ,并且繼續(xù)執(zhí)行下面的代碼 ?
echo 3333;
而swoole是可以實現(xiàn)的:
$http = new \Swoole\Http\Server("0.0.0.0", 9902);
$http->on('request', function ($request, $response)use($http) {
var_dump($request);
if(true)$http->shutdown(); // 接收指定請求后關閉http服務
});
$http->start(); // swoole可以實現(xiàn)的繼續(xù)執(zhí)行后面的內容
echo 'http服務關閉,繼續(xù)執(zhí)行后面的代碼……'.PHP_EOL;
完全可以參考workerman
的退出邏輯,自己寫一下就好了
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
// 創(chuàng)建一個Worker監(jiān)聽2345端口,使用http協(xié)議通訊
$http_worker = new Worker("http://0.0.0.0:2345");
// 啟動4個進程對外提供服務
$http_worker->count = 4;
// 接收到瀏覽器發(fā)送的數據時回復hello world給瀏覽器
$http_worker->onMessage = function(TcpConnection $connection, Request $request)
{
$uri = $request->uri();
if ($uri === '/stop') {
$connection->send('stop');
$master_pid = \is_file(Worker::$pidFile) ? (int)\file_get_contents(Worker::$pidFile) : 0;
$sig = \SIGQUIT;
// Send stop signal to master process.
$master_pid && \posix_kill($master_pid, $sig);
Worker::log("Workerman[$master_pid] stop fail");
// Timeout.
$timeout = 5;
$start_time = \time();
// Check master process is still alive?
while (1) {
$master_is_alive = $master_pid && \posix_kill((int) $master_pid, 0);
if ($master_is_alive) {
// Timeout?
if (\time() - $start_time >= $timeout) {
Worker::log("Workerman stop fail");
exit;
}
// Waiting amoment.
\usleep(10000);
continue;
}
// Stop success.
Worker::log("Workerman stop success");
exit(0);
}
} else {
$connection->send('hello world');
}
};
// 運行worker
Worker::runAll();
workerman 停止監(jiān)聽是 $worker->unlisten();
關閉客戶端是 $connection->close();
退出進程是Worker::stopAll();
swoole也無法執(zhí)行到3333
$server->start();
echo 3333;
感覺你的需求就是你發(fā)的這個 http://m.wtbis.cn/q/7957 ,關閉連接,然后重新建立一個新連接。這種需求和關閉服務和關閉進程以及執(zhí)行worker->run()后面的代碼沒有關系。代碼也很簡單。
$worker->onWorkerStart = function(){
// 每隔10秒用新token去連一次
$token = md5(time());
Timer::add(10, 'connect_with_token', [$token]);
};
function connect_with_token($token)
{
static $connection;
if ($connection) $connection->close();
$connection = new AsyncTcpConnection('ws://127.0.0.1:8000/ws/?token='.$token);
$connection->onMessage = function($connection, $data){
var_dump($data);
};
$connection->connect();
}
你的代碼我測試了,stop fail無法停止啊。代碼直接復制的,端口2345改為9902
然后需要停止后執(zhí)行Worker::runAll();之后的代碼,怎么實現(xiàn)?
$http = new \Swoole\Http\Server("0.0.0.0", 9902);
$http->on('request', function ($request, $response)use($http) {
var_dump($request);
if(true)$http->shutdown(); // 接收指定請求后關閉http服務
});
$http->start(); // swoole可以實現(xiàn)的繼續(xù)執(zhí)行后面的內容
echo 'http服務關閉,繼續(xù)執(zhí)行后面的代碼……'.PHP_EOL;
首先Workerman是一個純PHP實現(xiàn)的框架,在運行runAll()之后就阻塞在這里,所有的邏輯都在runAll內執(zhí)行,stop實際上走的是exit/die的方式,你也知道代碼里exit/die的結果就是后續(xù)代碼不會再執(zhí)行,所以runAll后續(xù)的代碼不會執(zhí)行
Swoole是個PHP擴展,start之后,Swoole會接管這部分,stop的時候也是由swoole去控制,走的未必是exit/die邏輯,所以后面的echo會執(zhí)行,如果你在代碼里使用了exit/die,swoole也不會執(zhí)行start之后的echo
你這么比較一個純PHP代碼實現(xiàn)的框架和一個PHP擴展有點不妥吧
我上面說的onWorkerStop是子進程關閉后的回調處理邏輯,每個子進程都會執(zhí)行一遍,如果你需要的是在主進程關閉后繼續(xù)處理邏輯,參考上面fuzqing的思路自行實現(xiàn)