<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## **Worker** 文檔列出屬性及靜態常量: ``` // $id // $name //全局的eventloop實例,可以向其注冊文件描述符的讀寫事件或者信號事件 //操作系統會將socket可寫可讀事件通過 select 或者 epoll的方法通知業務進程。業務進程通過調用 select 或者 epoll 來接收這個事件 // ::$globalEvent // connections // reloadable // user // transport // protocol // reusePort // count // ::$logFile // ::$daemonize runAll()中使用了 // ::$stdoutFile // ::$pidFile // ::runAll() // ::stopAll($code = 0, $log = '') // listen() ``` 回調屬性 ``` // onWorkerStart=function(Worker $worker){} // onConnect= function(TcpConnection $connection){} // onMessage=function(TcpConnection $connection, $data){} // onClose= function(TcpConnection $connection){} // onError= function(TcpConnection $connection, $code, $msg){} // onBufferFull = function(TcpConnection $connection){} // onBufferDrain = function(TcpConnection $connection){} // onWorkerReload = function(Worker $worker){} // onWorkerStop = function(Worker $worker){} // onWorkerExit = function(Worker $worker, $status, $pid){} ``` ### **示例** ``` require_once __DIR__ . '/vendor/autoload.php'; use Workerman\Worker; use Workerman\Connection\TcpConnection; // 此屬性為全局靜態屬性,用來設置Workerman進程的pid文件路徑,如果無特殊需要,注意:建議不要設置此屬性,此屬性必須在Worker::runAll();運行前設置才有效。windows系統不支持此特性 // 如果不設置,Workerman默認會在與Workerman目錄平行的位置自動生成一個pid文件 // 此項設置在監控中比較有用,例如將Workerman的pid文件放入固定的目錄中,可以方便一些監控軟件讀取pid文件,從而監控Workerman進程狀態 // Worker::$pidFile = '/var/run/workerman.pid'; // 運行 php start.php start 進入調試模式,這時代碼中的echo、var_dump、var_export等函數打印會在終端顯示 // 而運行 php start.php start -d則是進入daemon模式,也就是正式上線的運行模式,關閉終端不受影響。 // 如果想daemon方式運行時也能看到echo、var_dump、var_export等函數打印,可以設置Worker::$stdoutFile屬性 // 如果啟動命令使用了 -d參數,則該屬性會自動設置為true。也可以代碼中手動設置,如下: Worker::$daemonize = true;//注意:此屬性必須在Worker::runAll();運行前設置才有效。windows系統不支持此特性 // 所有的打印輸出全部保存在/tmp/stdout.log文件中 Worker::$stdoutFile = '/www/wwwroot/www.dash.vip/stdout.log'; // 指定workerman日志文件位置,此文件記錄了workerman自身相關的日志,包括啟動、停止等 // 如果沒有設置,文件名默認為workerman.log,文件位置位于Workerman的上一級目錄中 Worker::$logFile = '/www/wwwroot/www.dash.vip/workerman.log'; // <監聽地址> 可以為以下格式 // 是unix套接字,地址為本地一個磁盤路徑 // 非unix套接字,地址格式為 <本機ip>:<端口號> // new Worker()沒有參數時,不執行任何監聽的Worker容器,用來處理一些定時任務 // 運行在主進程,window不能在一個文件里實例多個Worker $worker0 = new Worker('unix:///www/wwwroot/www.dash.vip/my.sock');//$worker = new Worker('unix:///tmp/my_file') $worker = new Worker("tcp://0.0.0.0:2347"); // 啟動4個進程對外提供服務,如果是簡單業務則設置進程數與cpu合數一樣性能最好,如果有數據庫操作(數據查詢過程中有等待延遲)則設置進程數為cpu核數的3-6倍性能最好 $worker->count = 4; // 設置當前worker是否開啟監聽端口復用(socket的SO_REUSEPORT選項)。 // workerman多個進程獲取連接的方式默認是搶占式的,也就是說當客戶端有連接發起時,所有空閑的進程都有機會去獲取這個連接,快者先得。到底誰快,是由操作系統內核調度決定的。操作系統可能會優先選取最近一次使用的進程獲得cpu使用權,因為cpu寄存器里可能還存在上個進程的上下文信息,這可以減少上下文切換開銷。所以當業務足夠快的時候或者壓測過程中,更容易出現連接集中被某些進程處理的情況,因為這個策略可以避免頻繁的進程切換,性能往往是最優的 // 將獲取連接的方式從默認的搶占式改為輪詢的方式,輪詢的方式內核會將連接近似平均的方式分配給所有進程,這樣所有的進程將會一起處理請求(php>=7,Windows系統及 Mac OS 不支持此特性) $worker->reusePort = true;//可以提升多進程短連接應用的性能 // 設置當前Worker實例所使用的傳輸層協議,目前只支持3種(tcp、udp、ssl)。不設置默認為tcp // 設置當前Worker實例的名稱,方便運行【php ./start.php start status】命令時識別進程。其中worker_name就是顯示設置的實例名稱不設置時默認為none $worker->name = 'MyWebsocketWorker'; // 將"tcp://0.0.0.0:2347"應用層 協議改為Http $worker->protocol = 'Workerman\\Protocols\\Http'; // 設置當前Worker實例所使用的傳輸層協議,目前只支持3種(tcp、udp、ssl)。不設置默認為tcp $worker->transport = 'udp';// 傳輸層使用udp協議 // 設置當前Worker實例以哪個用戶運行。此屬性只有當前用戶為root時才能生效。不設置時默認以當前用戶運行,建議$user設置權限較低的用戶,例如www-data、apache、nobody等。 // 注意:此屬性必須在Worker::runAll();運行前設置才有效。windows系統不支持此特性。 $worker->user = 'www-data'; // 執行php start.php reload時會向所有子進程發送reload信號(SIGUSR1)。 // 默認true時,子進程收到reload信號后會自動退出然后主進程會自動拉起一個新的進程,一般用于更新業務代碼 // 當進程$reloadable為false時,收到reload信號后子進程收到reload信號不執行重啟,只會觸發 onWorkerReload $worker->reloadable = false; //設置reloadable屬性為false,即子進程收到reload信號不執行重啟,只會觸發 onWorkerReload $worker->onWorkerReload = function(Worker $worker){}; /* 當客戶端與Workerman建立連接時(TCP三次握手完成后)觸發的回調函數。每個連接只會觸發一次onConnect回調 注意:onConnect事件僅僅代表客戶端與Workerman完成了TCP三次握手,這時客戶端還沒有發來任何數據,此時除了通過$connection->getRemoteIp()獲得對方ip,沒有其他可以鑒別客戶端的數據或者信息,所以在onConnect事件里無法確認對方是誰。要想知道對方是誰,需要客戶端發送鑒權數據,例如某個token或者用戶名密碼之類,在onMessage回調里做鑒權。 由于udp是無連接的,所以當使用udp時不會觸發onConnect回調,也不會觸發onClose回調 */ $worker->onConnect = function(TcpConnection $connection) { echo "new connection from ip " . $connection->getRemoteIp() . "\n"; }; // Worker子進程啟動時的回調函數,每個子進程啟動時都會執行 $worker->onWorkerStart = function(Worker $worker){ echo "Worker {$worker->id} starting...\n"; // 實例化Worker后執行監聽,在Worker進程啟動后動態創建新的Worker實例,能夠實現同一個進程監聽多個端口,支持多種協議。需要注意的是用這種方法只是在當前進程增加監聽,并不會動態創建新的進程,也不會觸發onWorkerStart方法 // 例如一個http Worker啟動后實例化一個websocket Worker,那么這個進程即能通過http協議訪問,又能通過websocket協議訪問。由于websocket Worker和http Worker在同一個進程中,所以它們可以訪問共同的內存變量,共享所有socket連接。可以做到接收http請求,然后操作websocket客戶端完成向客戶端推送數據類似的效果 // 如果PHP版本<=7.0,則不支持在多個子進程中實例化相同端口的Worker。例如A進程創建了監聽2016端口的Worker,那么B進程就不能再創建監聽2016端口的Worker,否則會報Address already in use錯誤 /** * 4個進程啟動的時候都創建2016端口的Worker * 當執行到worker->listen()時會報Address already in use錯誤 * 如果worker->count=1則不會報錯 */ $inner_worker = new Worker('http://0.0.0.0:2016'); $inner_worker->onMessage = function(TcpConnection $connection, $data){}; // 執行監聽。這里會報Address already in use錯誤 $inner_worker->listen(); // 如果您的PHP版本>=7.0,可以設置Worker->reusePort=true, 這樣可以做到多個子進程創建相同端口的Worker $inner_worker = new Worker('http://0.0.0.0:2016'); // 設置端口復用,可以創建監聽相同端口的Worker(需要PHP>=7.0) $inner_worker->reusePort = true; $inner_worker->onMessage = function(TcpConnection $connection, $data){}; // 執行監聽。正常監聽不會報錯 $inner_worker->listen(); }; /* 每個連接都有一個單獨的應用層發送緩沖區,如果客戶端接收速度小于服務端發送速度,數據會在應用層緩沖區暫存,如果緩沖區滿(超過TcpConnection::$maxSendBufferSize上限)則會觸發onBufferFull回調 設置所有連接的默認應用層發送緩沖區大小,單位字節:TcpConnection::$defaultMaxSendBufferSize = 2*1024*1024; 也可以為當前連接動態設置緩沖區大小(默認值為1MB)例如:$connection->maxSendBufferSize = 102400; */ $worker->onBufferFull = function(TcpConnection $connection) { echo "bufferFull and do not send again\n"; }; /* 當發生onBufferFull事件時,開發者一般需要采取措施,例如停止向對端發送數據,等待發送緩沖區的數據被發送完畢(onBufferDrain事件)等 該回調在應用層發送緩沖區數據全部發送完畢后觸發。一般與onBufferFull配合使用,例如在onBufferFull時停止向對端繼續send數據,在onBufferDrain恢復寫入數據。 */ $worker->onBufferDrain = function(TcpConnection $connection) { echo "buffer drain and continue send\n"; }; // 當客戶端的連接上發生錯誤時觸發 $worker->onError = function(TcpConnection $connection, $code, $msg) { echo "error $code $msg\n"; }; /* 當客戶端通過連接發來數據時(Workerman收到數據時)觸發的回調函數,賦值過程運行在主進程 $data:客戶端連接上發來的數據,如果Worker指定了協議,則$data是對應協議decode(解碼)了的數據。數據類型與協議decode()實現有關,websocket text frame 為字符串,HTTP協議為 Workerman\Protocols\Http\Request對象。 */ $worker->onMessage = function(TcpConnection $connection, $data) { $worker->id;//進程id編號 編號從0計數,最大值為($tcp_worker->count)-1 // 當進程收到SIGALRM信號時,打印輸出一些信息 Worker::$globalEvent->add(SIGALRM, EventInterface::EV_SIGNAL, function() { echo "Get signal SIGALRM\n"; }); // 這部分運行在子進程 // $connection->send('hello ' . $data); // 定時,每10秒一次 Timer::add(10, function()use($worker) { // 遍歷當前進程所有的客戶端連接,發送當前服務器的時間 foreach($worker->connections as $connection) { $connection->send(time()); } }); // 已經處理請求數 static $request_count = 0; // 如果請求數達到1000 if(++$request_count >= MAX_REQUEST) { /* * 退出當前進程,主進程會立刻重新啟動一個全新進程補充上來 * 從而完成進程重啟 */ Worker::stopAll(); } }; // 當客戶端連接與Workerman斷開時觸發的回調函數。不管連接是如何斷開的,只要斷開就會觸發onClose。每個連接只會觸發一次onClose // 由于udp是無連接的,所以當使用udp時不會觸發onConnect回調,也不會觸發onClose回調 $worker->onClose = function(TcpConnection $connection) { echo "connection closed\n"; }; // 進程關閉(停止)時觸發 $worker->onWorkerStop = function($worker) { //通知運維人員 //sc('WebSocket服務進程退出,如非定時重啟,請檢查!'); }; // 當工作進程退出時觸發 $worker->onWorkerExit=function($worker, $status, $pid){}; // 一個文件里同時new 多個 Worker,那么runAll也會運行多個Worker實例 // 注意windows里同一個文件不能同時new 多個Worker Worker::runAll(); ``` ![](https://img.kancloud.cn/b2/18/b218e94fe6cd8ff5a127f4f6df12bcd5_860x160.png) ``` // VERSION workman版本 // STATUS_STARTING 開始狀態 // STATUS_RUNNING 運行狀態 // STATUS_SHUTDOWN 關閉狀態 // STATUS_RELOADING 重新加載狀態 // DEFAULT_BACKLOG 默認backlog。Backlog是掛起連接隊列的最大長度 // MAX_UDP_PACKAGE_SIZE 最大udp包大小 // UI_SAFE_LENGTH 相鄰列(columns)的安全距離 // group Unix進程組需要適當的權限(通常是root) // stopping 進程是否停止默認false // ::$statusFile 用于存儲主進程狀態文件的文件嗎默認'' // ::$onMasterReload 當主進程收到重載信號時觸發 // ::$onMasterStop 主進程終止時觸發 // ::$eventLoopClass // ::$processTitle 進程標題 // ::$stopTimeout 在向子進程發送停止命令stopTimeout設置的秒后,如果子進程仍在運行,則強制終止 // ::checkSapiEnv() 檢查sapi // ::init() runAll()中使用了 // ::reloadAllWorkers() runAll()中使用了 重新加載所有工作實例 // ::resetStd() runAll()中使用了 重定向標準輸入和輸出 // ::getAllWorkers() 獲取所有worker實例 // ::getEventLoop() 獲取全局事件循環實例 // ::getMainSocket() 獲取主套接字資源 // ::getUiColumns() 獲取終端中顯示的UI列 // ::getSingleLineTotalLength() 獲取ui的單行總長度 // ::signalHandler($signal) 信號處理器 // ::getStartFilesForWindows() 獲取windows的啟動文件$argv // ::forkOneWorkerForWindows($start_file) 分叉(Fork)一個worker進程 // ::checkWorkerStatusForWindows() 檢查windows的worker狀態 // ::checkIfChildRunning() 檢查子進程是否真的在運行 // ::getStatus() 獲取進程狀態 // ::getGracefulStop() 如果優雅地停止 // ::checkErrors() 當前進程退出時檢查錯誤 // ::log($msg) 記錄日志到static::$logFile文件 // ::safeEcho($msg, $decorated = false) 安全的輸出(阻止輸出錯誤信息到流,即只輸出$msg到流fwrite($stream, $msg)) // __construct($socket_name = '', array $context_option = array()) // setUserAndGroup() 為當前進程設置unix用戶和組 // unlisten() 停止監聽 // pauseAccept() 暫停接受新連接 // resumeAccept() 恢復并接受新連接 // getSocketName() 獲取套接字(Socket)名稱 // run() 運行工作實例 // stop() 停止當前工作實例 // acceptConnection($socket) 接受連接 // acceptUdpConnection($socket) 對于udp包 ``` 般來說在`Worker::runAll();`調用前運行的代碼都是在主進程運行的,onXXX回調運行的代碼都屬于子進程。注意寫在`Worker::runAll();`后面的代碼永遠不會被執行 ## **new Worker()沒有參數時,不執行任何監聽的Worker容器,用來處理一些定時任務** ``` use \Workerman\Worker; use \Workerman\Timer; require_once __DIR__ . '/vendor/autoload.php'; $task = new Worker(); $task->onWorkerStart = function($task) { // 每2.5秒執行一次 $time_interval = 2.5; Timer::add($time_interval, function() { echo "task run\n"; }); }; // 運行worker Worker::runAll(); ``` ## **配置ssl證書** ``` use Workerman\Worker; use Workerman\Connection\TcpConnection; require_once __DIR__ . '/vendor/autoload.php'; // 證書最好是申請的證書 $context = array( 'ssl' => array( 'local_cert' => '/etc/nginx/conf.d/ssl/server.pem', // 也可以是crt文件 'local_pk' => '/etc/nginx/conf.d/ssl/server.key', ) ); // 這里設置的是websocket協議 $worker = new Worker('websocket://0.0.0.0:4431', $context); // 設置transport開啟ssl,websocket+ssl即wss $worker->transport = 'ssl'; $worker->onMessage = function(TcpConnection $con, $msg) { $con->send('ok'); }; Worker::runAll(); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看