欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

php使用swoole實現(xiàn)TCP服務(wù)

 更新時間:2024年04月03日 08:31:09   作者:huaweichenai  
這篇文章主要為大家詳細介紹了php如何使用swoole實現(xiàn)TCP服務(wù),文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下

這里以在Yii框架下示例

一:swoole配置TCP

'swoole' => [
    // 日志文件路徑
    'log_file' => '@console/log/swoole.log',
    // 設(shè)置swoole_server錯誤日志打印的等級,范圍是0-5。低于log_level設(shè)置的日志信息不會拋出
    'log_level' => 1,
    // 進程的PID存儲文件
    'pid_file' => '@console/log/swoole.server.pid',

    // HTTP協(xié)議配置
    'http' => [
        'host' => '0.0.0.0',
        'port' => '8889',

        // 異步任務(wù)的工作進程數(shù)量
        'task_worker_num' => 4,
    ],
    // TCP協(xié)議配置
    'tcp' => [
        'host' => '0.0.0.0',
        'port' => '14000',

        // 異步任務(wù)的工作進程數(shù)量
        'task_worker_num' => 4,

        // 啟用TCP-Keepalive死連接檢測
        'open_tcp_keepalive' => 1,
        // 單位秒,連接在n秒內(nèi)沒有數(shù)據(jù)請求,將開始對此連接進行探測
        'tcp_keepidle' => 5 * 60,
        // 探測的次數(shù),超過次數(shù)后將close此連接
        'tcp_keepcount' => 3,
        // 探測的間隔時間,單位秒
        'tcp_keepinterval' => 60,

        // 心跳檢測,此選項表示每隔多久輪循一次,單位為秒
        'heartbeat_check_interval' => 2 * 60,
        // 心跳檢測,連接最大允許空閑的時間
        'heartbeat_idle_time' => 5 * 60,
    ]
],

二:swoole實現(xiàn)TCP服務(wù)基類

<?php
/**
 * @link http://www.u-bo.com
 * @copyright 南京友博網(wǎng)絡(luò)科技有限公司
 * @license http://www.u-bo.com/license/
 */

namespace console\swoole;

use Yii;
use yii\helpers\Console;
use yii\helpers\ArrayHelper;

/*
 * Swoole Server基類
 *
 * @author wangjian
 * @since 0.1
 */
abstract class BaseServer
{
    /**
     * @var Swoole\Server
     */
    public $swoole;
    /**
     * @var boolean DEBUG
     */
    public $debug = false;

    /**
     * __construct
     */
    public function __construct($httpConfig, $tcpConfig, $config = [])
    {
        $httpHost = ArrayHelper::remove($httpConfig, 'host');
        $httpPort = ArrayHelper::remove($httpConfig, 'port');
        $this->swoole = new \swoole_http_server($httpHost, $httpPort);
        $this->swoole->set(ArrayHelper::merge($config, $httpConfig));

        $this->swoole->on('start', [$this, 'onStart']);
        $this->swoole->on('request', [$this, 'onRequest']);
        $this->swoole->on('WorkerStart', [$this, 'onWorkerStart']);
        $this->swoole->on('WorkerStop', [$this, 'onWorkerStop']);
        $this->swoole->on('task', [$this, 'onTask']);
        $this->swoole->on('finish', [$this, 'onTaskFinish']);

        $this->swoole->on('shutdown', [$this, 'onShutdown']);

        $tcpHost = ArrayHelper::remove($tcpConfig, 'host');
        $tcpPort = ArrayHelper::remove($tcpConfig, 'port');
        $tcpServer = $this->swoole->listen($tcpHost, $tcpPort, SWOOLE_SOCK_TCP);
        $tcpServer->set($tcpConfig);
        $tcpServer->on('connect', [$this, 'onConnect']);
        $tcpServer->on('receive', [$this, 'onReceive']);
        $tcpServer->on('close', [$this, 'onClose']);
    }

    /*
     * 啟動server
     */
    public function run()
    {
        $this->swoole->start();
    }

    /**
     * Server啟動在主進程的主線程時的回調(diào)事件處理
     *
     * @param swoole_server $server
     */
    public function onStart(\swoole_server $server)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("**Server Start**\n", Console::FG_GREEN);
        $this->stdout("master_pid: ");
        $this->stdout("{$server->master_pid}\n", Console::FG_BLUE);

        $this->onStartHandle($server);

        $this->afterExec($startedAt);
    }

    /**
     * 客戶端與服務(wù)器建立連接后的回調(diào)事件處理
     *
     * @param swoole_server $server
     * @param integer $fd
     * @param integer $reactorId
     */
    abstract public function onConnect(\swoole_server $server, int $fd, int $reactorId);

    /**
     * 當服務(wù)器收到來自客戶端的數(shù)據(jù)時的回調(diào)事件處理
     *
     * @param swoole_server $server
     * @param integer $fd
     * @param integer $reactorId
     * @param string $data
     */
    abstract public function onReceive(\swoole_server $server, int $fd, int $reactorId, string $data);

    /**
     * 當服務(wù)器收到來自客戶端的HTTP請求時的回調(diào)事件處理
     *
     * @param swoole_http_request $request
     * @param swoole_http_response $response
     */
    abstract public function onRequest(\swoole_http_request $request, \swoole_http_response $response);

    /**
     * Worker進程/Task進程啟動時發(fā)生
     *
     * @param swoole_server $server
     * @param integer $worker_id
     */
    abstract public function onWorkerStart(\swoole_server $server, int $worker_id);

    /**
     * Worker進程/Task進程終止時發(fā)生
     *
     * @param swoole_server $server
     * @param integer $worker_id
     */
    abstract public function onWorkerStop(\swoole_server $server, int $worker_id);

    /**
     * 異步任務(wù)處理
     *
     * @param swoole_server $server
     * @param integer $taskId
     * @param integer $srcWorkerId
     * @param mixed $data
     */
    abstract public function onTask(\swoole_server $server, int $taskId, int $srcWorkerId, mixed $data);

    /**
     * 異步任務(wù)處理完成
     *
     * @param swoole_server $server
     * @param integer $taskId
     * @param mixed $data
     */
    abstract public function onTaskFinish(\swoole_server $server, int $taskId, mixed $data);

    /**
     * 客戶端與服務(wù)器斷開連接后的回調(diào)事件處理
     *
     * @param swoole_server $server
     * @param integer $fd
     */
    abstract public function onClose(\swoole_server $server, $fd);

    /**
     * Server正常結(jié)束時的回調(diào)事件處理
     *
     * @param swoole_server $server
     */
    public function onShutdown(\swoole_server $server)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("**Server Stop**\n", Console::FG_GREEN);
        $this->stdout("master_pid: ");
        $this->stdout("{$server->master_pid}\n", Console::FG_BLUE);

        $this->onShutdownHandle($server);

        $this->afterExec($startedAt);
    }

    /**
     * Server啟動在主進程的主線程時的自定義事件處理
     *
     * @param swoole_server $server
     */
    protected function onStartHandle(\swoole_server $server)
    {

    }

    /**
     * Server正常結(jié)束時的自定義事件處理
     *
     * @param swoole_server $server
     */
    protected function onShutdownHandle(\swoole_server $server)
    {

    }

    /**
     * 獲取請求路由
     *
     * @param swoole_http_request $request
     */
    protected function getRoute(\swoole_http_request $request)
    {
        return ltrim($request->server['request_uri'], '/');
    }

    /**
     * 獲取請求的GET參數(shù)
     *
     * @param swoole_http_request $request
     */
    protected function getParams(\swoole_http_request $request)
    {
        return $request->get;
    }

    /**
     * 解析收到的數(shù)據(jù)
     *
     * @param string $data
     */
    protected function decodeData($data)
    {
        return json_decode($data, true);
    }

    /**
     * Before Exec
     */
    protected function beforeExec()
    {
        $startedAt = microtime(true);
        $this->stdout(date('Y-m-d H:i:s') . "\n", Console::FG_YELLOW);
        return $startedAt;
    }

    /**
     * After Exec
     */
    protected function afterExec($startedAt)
    {
        $duration = number_format(round(microtime(true) - $startedAt, 3), 3);
        $this->stdout("{$duration} s\n\n", Console::FG_YELLOW);
    }

    /**
     * Prints a string to STDOUT.
     */
    protected function stdout($string)
    {
        if (Console::streamSupportsAnsiColors(\STDOUT)) {
            $args = func_get_args();
            array_shift($args);
            $string = Console::ansiFormat($string, $args);
        }
        return Console::stdout($string);
    }
}

三:swoole操作類(繼承swoole基類)

<?php
/**
 * @link http://www.u-bo.com
 * @copyright 南京友博網(wǎng)絡(luò)科技有限公司
 * @license http://www.u-bo.com/license/
 */

namespace console\swoole;

use Yii;
use yii\db\Query;
use yii\helpers\Console;
use yii\helpers\VarDumper;
use apps\sqjc\models\WaterLevel;
use apps\sqjc\models\WaterLevelLog;
use common\models\Bayonet;
use common\models\Device;
use common\models\DeviceCategory;

/**
 * Swoole Server測試類
 *
 * @author wangjian
 * @since 1.0
 */
class Server extends BaseServer
{
    /**
     * @inheritdoc
     */
    public function onConnect($server, $fd, $reactorId)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("**Connection Open**\n", Console::FG_GREEN);
        $this->stdout("fd: ");
        $this->stdout("{$fd}\n", Console::FG_BLUE);

        $this->afterExec($startedAt);
    }

    /**
     * @inheritdoc
     */
    public function onReceive($server, $fd, $reactorId, $data)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("**Received Message**\n", Console::FG_GREEN);

        $this->stdout("fd: ");
        $this->stdout("{$fd}\n", Console::FG_BLUE);

        $this->stdout("data: ");//接收的數(shù)據(jù)
        $this->stdout("{$data}\n", Console::FG_BLUE);



        $result = $server->send($fd, '回復消息');



        $this->afterExec($startedAt);
    }


    /**
     * @inheritdoc
     */
    public function onRequest($request, $response)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("**HTTP Request**\n", Console::FG_GREEN);

        $this->stdout("fd: ");
        $this->stdout("{$request->fd}\n", Console::FG_BLUE);

        $response->status(200);
        $response->end('success');

        $this->afterExec($startedAt);
    }

    /**
     * @inheritdoc
     */
    public function onClose($server, $fd)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("**Connection Close**\n", Console::FG_GREEN);

        $this->stdout("fd: ");
        $this->stdout("{$fd}\n", Console::FG_BLUE);

        $this->afterExec($startedAt);
    }



    /**
     * @inheritdoc
     */
    public function onTask($server, $taskId, $srcWorkerId, $data)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("New AsyncTask: ");
        $this->stdout("{$taskId}\n", Console::FG_BLUE);
        $this->stdout("{$data}\n", Console::FG_BLUE);

        $server->finish($data);

        $this->afterExec($startedAt);
    }

    /**
     * @inheritdoc
     */
    public function onWorkerStop($server, $worker_id)
    {
        // Yii::$app->db->close();
    }
    /**
     * @inheritdoc
     */
    public function onWorkerStart($server, $worker_id)
    {
        // Yii::$app->db->open();
    }


    /**
     * @inheritdoc
     */
    public function onTaskFinish($server, $taskId, $data)
    {
        $startedAt = $this->beforeExec();

        $this->stdout("AsyncTask finished: ");
        $this->stdout("{$taskId}\n", Console::FG_BLUE);

        $this->afterExec($startedAt);
    }
}

四:操作TCP服務(wù)

<?php
/**
 * @link http://www.u-bo.com
 * @copyright 南京友博網(wǎng)絡(luò)科技有限公司
 * @license http://www.u-bo.com/license/
 */

namespace console\controllers;

use Yii;
use yii\helpers\Console;
use yii\helpers\FileHelper;
use yii\helpers\ArrayHelper;
use console\swoole\Server;

/**
 * WebSocket Server controller.
 *
 * @see https://github.com/tystudy/yii2-swoole-websocket/blob/master/README.md
 *
 * @author wangjian
 * @since 1.0
 */
class SwooleController extends Controller
{
    /**
     * @var string 監(jiān)聽IP
     */
    public $host;
    /**
     * @var string 監(jiān)聽端口
     */
    public $port;
    /**
     * @var boolean 是否以守護進程方式啟動
     */
    public $daemon = false;
    /**
     * @var boolean 是否啟動測試類
     */
    public $test = false;

    /**
     * @var array Swoole參數(shù)配置項
     */
    private $_params;

    /**
     * @var array Swoole參數(shù)配置項(HTTP協(xié)議)
     */
    private $_http_params;
    /**
     * @var array Swoole參數(shù)配置項(TCP協(xié)議)
     */
    private $_tcp_params;

    /**
     * @inheritdoc
     */
    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            //判斷是否開啟swoole拓展
            if (!extension_loaded('swoole')) {
                return false;
            }

            //獲取swoole配置信息
            if (!isset(Yii::$app->params['swoole'])) {
                return false;
            }
            $this->_params = Yii::$app->params['swoole'];
            $this->_http_params = ArrayHelper::remove($this->_params, 'http');
            $this->_tcp_params = ArrayHelper::remove($this->_params, 'tcp');

            foreach ($this->_params as &$param) {
                if (strncmp($param, '@', 1) === 0) {
                    $param = Yii::getAlias($param);
                }
            }

            $this->_params = ArrayHelper::merge($this->_params, [
                'daemonize' => $this->daemon
            ]);

            return true;
        } else {
            return false;
        }
    }
    /**
     * 啟動服務(wù)
     */
    public function actionStart()
    {
        if ($this->getPid() !== false) {
            $this->stdout("WebSocket Server is already started!\n", Console::FG_RED);
            return self::EXIT_CODE_NORMAL;
        }
        $server = new Server($this->_http_params, $this->_tcp_params, $this->_params);
        $server->run();
    }

    /**
     * 停止服務(wù)
     */
    public function actionStop()
    {
        $pid = $this->getPid();
        if ($pid === false) {
            $this->stdout("Tcp Server is already stoped!\n", Console::FG_RED);
            return self::EXIT_CODE_NORMAL;
        }

        \swoole_process::kill($pid);
    }

    /**
     * 清理日志文件
     */
    public function actionClearLog()
    {
        $logFile = Yii::getAlias($this->_params['log_file']);
        FileHelper::unlink($logFile);
    }

    /**
     * 獲取進程PID
     *
     * @return false|integer PID
     */
    private function getPid()
    {
        $pidFile = $this->_params['pid_file'];
        if (!file_exists($pidFile)) {
            return false;
        }

        $pid = file_get_contents($pidFile);
        if (empty($pid)) {
            return false;
        }

        $pid = intval($pid);
        if (\swoole_process::kill($pid, 0)) {
            return $pid;
        } else {
            FileHelper::unlink($pidFile);
            return false;
        }
    }

    /**
     * @inheritdoc
     */
    public function options($actionID)
    {
        return ArrayHelper::merge(parent::options($actionID), [
            'daemon',
            'test'
        ]);
    }

    /**
     * @inheritdoc
     */
    public function optionAliases()
    {
        return ArrayHelper::merge(parent::optionAliases(), [
            'd' => 'daemon',
            't' => 'test',
        ]);
    }
}

以上就是php使用swoole實現(xiàn)TCP服務(wù)的詳細內(nèi)容,更多關(guān)于php swoole實現(xiàn)TCP服務(wù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • thinkphp3.0 模板中函數(shù)的使用

    thinkphp3.0 模板中函數(shù)的使用

    thinkphp3.0 模板中函數(shù)的使用,不是所有的變量都能使用函數(shù)
    2012-11-11
  • 詳解PHP Swoole與TCP三次握手

    詳解PHP Swoole與TCP三次握手

    TCP(Transmission Control Protocol 傳輸控制協(xié)議)是一種面向連接(連接導向)的、可靠的、 基于IP的傳輸層協(xié)議。TCP在IP報文的協(xié)議號是6。TCP是一個超級麻煩的協(xié)議,而它又是互聯(lián)網(wǎng)的基礎(chǔ),也是每個程序員必備的基本功。本文將詳細介紹PHP Swoole與TCP三次握手。
    2021-05-05
  • 神盾加密解密教程(一)PHP變量可用字符

    神盾加密解密教程(一)PHP變量可用字符

    這篇教程首先講PHP變量可用字符,是因為要解密神盾加密的程序,了解PHP變量可用字符是解密的首要條件,好了,廢話不多說,直接進入正題
    2014-05-05
  • php三種實現(xiàn)多線程類似的方法

    php三種實現(xiàn)多線程類似的方法

    這篇文章主要介紹了php三種實現(xiàn)多線程類似的方法,需要的朋友可以參考下
    2015-10-10
  • PHP面向?qū)ο蟪绦蛟O(shè)計繼承用法簡單示例

    PHP面向?qū)ο蟪绦蛟O(shè)計繼承用法簡單示例

    這篇文章主要介紹了PHP面向?qū)ο蟪绦蛟O(shè)計繼承用法,結(jié)合具體實例形式分析了php面向?qū)ο蟪绦蛟O(shè)計中繼承的相關(guān)概念、原理、使用技巧與相關(guān)操作注意事項,需要的朋友可以參考下
    2018-12-12
  • phpQuery采集網(wǎng)頁實現(xiàn)代碼實例

    phpQuery采集網(wǎng)頁實現(xiàn)代碼實例

    這篇文章主要介紹了phpQuery采集網(wǎng)頁實現(xiàn)代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • PHP __autoload函數(shù)(自動載入類文件)的使用方法

    PHP __autoload函數(shù)(自動載入類文件)的使用方法

    在使用PHP的OO模式開發(fā)系統(tǒng)時,通常大家習慣上將每個類的實現(xiàn)都存放在一個單獨的文件里,這樣會很容易實現(xiàn)對類進行復用,同時將來維護時也很便利
    2012-02-02
  • PHP與Web頁面的交互示例詳解二

    PHP與Web頁面的交互示例詳解二

    這篇文章主要介紹了PHP與Web頁面的交互示例詳解二,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • 自由掌控下載速度:PHP實現(xiàn)文件限速

    自由掌控下載速度:PHP實現(xiàn)文件限速

    文件限速是一種控制文件下載速度的技術(shù),可以防止服務(wù)器過載和保護用戶體驗,本文將介紹如何使用PHP實現(xiàn)文件限速功能,通過控制文件的輸出速度來限制下載速度,需要的朋友可以參考下
    2023-10-10
  • php 小乘法表實現(xiàn)代碼

    php 小乘法表實現(xiàn)代碼

    隨便寫寫小程序,促進自己對php的熱情,希望我能堅持下去
    2009-07-07

最新評論