摘要:主進程會重新啟動一個新的進程來處理任務服務器程序,最大允許的連接數,如此參數用來設置最大允許維持多少個連接。如果沒有注冊,服務器程序將無法啟動。增加是為了防止服務器程序重啟,導致復用上一次的消息隊列數據,讀取到錯誤的數據守護進程化。
限于本人的技術水準不高,文章中如果有問題的地方希望各位老爺們能夠告訴我。
今天說swoole的通訊。
這個swoole的官網首頁已經有了例子,TCP Server和TCP Client
官網demo
其實是四個步驟 官網詳細介紹
構建Server對象
設置運行時參數
注冊事件回調函數
啟動服務器
其中 設置運行參數看這里所有的設置參數
為了方便大家看 ,我自己做了整理,看看就好
2,通過此參數來調節(jié)主進程內事件處理線程的數量,以充分利用多核。默認會啟用CPU核數相同的數量。 // reactor_num一般設置為CPU核數的1-4倍,在swoole中reactor_num最大不得超過CPU核數*4。 // swoole的reactor線程是可以利用多核,如:機器有128核,那么swoole會啟動128線程。每個線程能都會維持一個EventLoop。線程之間是無鎖的, // 指令可以被128核CPU并行執(zhí)行??紤]到操作系統調度存在一定程度的偏差,可以設置為CPU核數*2,以便最大化利用CPU的每一個核。 $setConfig["reactor_num"]=2; // 設置啟動的worker進程數。 // 業(yè)務代碼是全異步非阻塞的,這里設置為CPU的1-4倍最合理 // 業(yè)務代碼為同步阻塞,需要根據請求響應時間和系統負載來調整 // 比如1個請求耗時100ms,要提供1000QPS的處理能力,那必須配置100個進程或更多。 // 但開的進程越多,占用的內存就會大大增加,而且進程間切換的開銷就會越來越大。所以這里適當即可。不要配置過大。 // 每個進程占用40M內存,那100個進程就需要占用4G內存 $setConfig["worker_num"]=4; // 設置worker進程的最大任務數。一個worker進程在處理完超過此數值的任務后將自動退出。這個參數是為了防止PHP進程內存溢出。 // 如果不希望進程自動退出可以設置為0 // 當worker進程內發(fā)生致命錯誤或者人工執(zhí)行exit時,進程會自動退出。主進程會重新啟動一個新的worker進程來處理任務 $setConfig["max_request"]=2000; // 服務器程序,最大允許的連接數,如max_conn => 10000, 此參數用來設置Server最大允許維持多少個tcp連接。超過此數量后,新進入的連接將被拒絕。 // max_connection最大不得超過操作系統ulimit -n的值,否則會報一條警告信息,并重置為ulimit -n的值 // max_connection默認值為ulimit -n的值 // WARN swServer_start_check: serv->max_conn is exceed the maximum value[100000]. // 此參數不要調整的過大,根據機器內存的實際情況來設置。Swoole會根據此數值一次性分配一塊大內存來保存Connection信息 $setConfig["max_conn"]=10000; // 配置task進程的數量,配置此參數后將會啟用task功能。所以swoole_server務必要注冊onTask/onFinish2個事件回調函數。如果沒有注冊,服務器程序將無法啟動。 // task進程是同步阻塞的,配置方式與worker同步模式一致。 // task進程內不能使用swoole_server->task方法 // task進程內不能使用mysql-async/redis-async/swoole_event等異步IO函數 $setConfig["task_worker_num"]=2; // 設置task進程與worker進程之間通信的方式。 // 1, 使用unix socket通信 // 2, 使用消息隊列通信 // 3, 使用消息隊列通信,并設置為爭搶模式 // 設置為3后,task/taskwait將無法指定目標進程ID $setConfig["task_ipc_mode"]=3; // 設置task進程的最大任務數。一個task進程在處理完超過此數值的任務后將自動退出。 // 這個參數是為了防止PHP進程內存溢出。如果不希望進程自動退出可以設置為0。 // task_max_request默認為5000,受swoole_config.h的SW_MAX_REQUEST宏控制 // 1.7.17以上版本默認值調整為0,不會主動退出進程 $setConfig["task_max_request"]=5000; // 設置task的數據臨時目錄,在swoole_server中,如果投遞的數據超過8192字節(jié), // 將啟用臨時文件來保存數據。這里的task_tmpdir就是用來設置臨時文件保存的位置。 // 需要swoole-1.7.7+ $setConfig["task_tmpdir"]="/tmp/tasl_tmpdir/";//路徑我是隨便寫的 // 數據包分發(fā)策略??梢赃x擇3種類型,默認為2 // 1,輪循模式,收到會輪循分配給每一個worker進程 // 2,固定模式,根據連接的文件描述符分配worker。這樣可以保證同一個連接發(fā)來的數據只會被同一個worker處理 // 3,搶占模式,主進程會根據Worker的忙閑狀態(tài)選擇投遞,只會投遞給處于閑置狀態(tài)的Worker // 4,IP分配,根據TCP/UDP連接的來源IP進行取模hash,分配給一個固定的worker進程。 // 可以保證同一個來源IP的連接數據總會被分配到同一個worker進程 // 5,UID分配,需要用戶代碼中調用$serv->bind() 將一個連接綁定1個uid。然后swoole根據UID的值分配到不同的worker進程 // dispatch_mode 4,5兩種模式,在 1.7.8以上版本可用 // dispatch_mode=1/3時,底層會屏蔽onConnect/onClose事件,原因是這2種模式下無法保證onConnect/onClose/onReceive的順序 // 非請求響應式的服務器程序,請不要使用模式1或3 // SWOOLE_BASE模式 // dispatch_mode 配置在BASE模式是無效的,因為BASE不存在投遞任務。 // 當reactor收到客戶端發(fā)來的數據后會立即回調onReceive,不需要投遞Worker進程。 $setConfig["dispatch_mode"]=2; // 設置消息隊列的KEY,僅在ipc_mode = 2或task_ipc_mode = 2時使用。 // 設置的Key僅作為隊列的基數。此參數的默認值為ftok($php_script_file, 1)。實際使用的消息隊列KEY為: // recv數據消息隊列KEY為 message_queue_key // send數據消息隊列KEY為 message_queue_key + 1 // task數據消息隊列KEY為 message_queue_key + 2 // recv/send數據隊列在server結束后,會自動銷毀。 // task隊列在server結束后不會銷毀,重新啟動程序后,task進程仍然會接著處理隊列中的任務。 // 1.7.8以前的版本,KEY會+serv->master_pid。增加pid是為了防止服務器程序重啟,導致復用上一次的消息隊列數據,讀取到錯誤的數據 $setConfig["message_queue_key"]=2; // 守護進程化。設置daemonize => 1時,程序將轉入后臺作為守護進程運行。長時間運行的服務器端程序必須啟用此項。 // 如果不啟用守護進程,當ssh終端退出后,程序將被終止運行。 // 啟用守護進程后,標準輸入和輸出會被重定向到 log_file // 如果未設置log_file,將重定向到 /dev/null,所有打印屏幕的信息都會被丟棄 $setConfig["daemonize"]=1; // Listen隊列長度,如backlog => 128,此參數將決定最多同時有多少個等待accept的連接。 // 與php-fpm/apache等軟件不同,swoole并不依賴backlog來解決連接排隊的問題。所以不需要設置太大的backlog參數。 $setConfig["backlog"]= 128; // log_file => "/data/log/swoole.log", 指定swoole錯誤日志文件。 // 在swoole運行期發(fā)生的異常信息會記錄到這個文件中。默認會打印到屏幕。 // 注意log_file不會自動切分文件,所以需要定期清理此文件。 // 觀察log_file的輸出,可以得到服務器的各類異常信息和警告。 // log_file中的日志僅僅是做運行時錯誤記錄,沒有長久存儲的必要。 // 開啟守護進程模式后(daemonize => true),標準輸出將會被重定向到log_file。 // 在PHP代碼中echo/var_dump/print等打印到屏幕的內容會寫入到log_file文件 $setConfig["log_file"]="/data/log/swoole.log"; // 啟用心跳檢測,此選項表示每隔多久輪循一次,單位為秒。 // 如 heartbeat_check_interval => 60,表示每60秒,遍歷所有連接,如果該連接在60秒內,沒有向服務器發(fā)送任何數據,此連接將被強制關閉。 // swoole_server并不會主動向客戶端發(fā)送心跳包,而是被動等待客戶端發(fā)送心跳。 // 服務器端的heartbeat_check僅僅是檢測連接上一次發(fā)送數據的時間,如果超過限制,將切斷連接。 // heartbeat_check僅支持TCP連接 $setConfig["heartbeat_check_interval"]=60; // 與heartbeat_check_interval配合使用。表示連接最大允許空閑的時間。如 // array( // "heartbeat_idle_time" => 600, // "heartbeat_check_interval" => 60, // ); // 表示每60秒遍歷一次,一個連接如果600秒內未向服務器發(fā)送任何數據,此連接將被強制關閉。 $setConfig["heartbeat_idle_time"]=600; // 打開EOF檢測,此選項將檢測客戶端連接發(fā)來的數據,當數據包結尾是指定的字符串時才會投遞給Worker進程。 // 否則會一直拼接數據包,直到超過緩存區(qū)或者超時才會中止。當出錯時swoole底層會認為是惡意連接,丟棄數據并強制關閉連接。 // array( // "open_eof_check" => true, //打開EOF檢測 // "package_eof" => " ", //設置EOF // ) // 常見的Memcache/SMTP/POP等協議都是以 結束的,就可以使用此配置。 //開啟后可以保證Worker進程一次性總是收到一個或者多個完整的數據包。 // EOF檢測不會從數據中間查找eof字符串,所以Worker進程可能會同時收到多個數據包, // 需要在應用層代碼中自行explode(" ", $data) 來拆分數據包 // 1.7.15版本增加了open_eof_split,支持從數據中查找EOF,并切分數據 $setConfig["open_eof_check"]=1; // package_eof // 與open_eof_check配合使用,設置EOF字符串。 // package_eof最大只允許傳入8個字節(jié)的字符串 $setConfig["package_eof"]=" "; // open_eof_split // 啟用EOF自動分包。當設置open_eof_check后,底層檢測數據是否以特定的字符串結尾來進行數據緩沖。 // 但默認只截取收到數據的末尾部分做對比。這時候可能會產生多條數據合并在一個包內。 // 啟用open_eof_split參數后,底層會從數據包中間查找EOF,并拆分數據包。 // onReceive每次僅收到一個以EOF字串結尾的數據包。 // open_eof_split在1.7.15以上版本可用 $setConfig["open_eof_split"]=1; // 打開包長檢測特性。包長檢測提供了固定包頭+包體這種格式協議的解析。 // 啟用后,可以保證Worker進程onReceive每次都會收到一個完整的數據包。 $setConfig["open_length_check"]=1; // s :有符號、主機字節(jié)序、2字節(jié)短整型 // S:無符號、主機字節(jié)序、2字節(jié)短整型 // n:無符號、網絡字節(jié)序、2字節(jié)短整型 // N:無符號、網絡字節(jié)序、4字節(jié)整型 // l:有符號、主機字節(jié)序、2字節(jié)短整型(小寫L) // L:無符號、主機字節(jié)序、2字節(jié)短整型(大寫L) $setConfig["package_length_type"]="s"; // 設置最大數據包尺寸,開啟open_length_check/open_eof_check/open_http_protocol等協議解析后。 // swoole底層會進行數據包拼接。這時在數據包未收取完整時,所有數據都是保存在內存中的。 // 所以需要設定package_max_length,一個數據包最大允許占用的內存尺寸。 // 如果同時有1萬個TCP連接在發(fā)送數據,每個數據包2M,那么最極限的情況下,就會占用20G的內存空間。 // open_length_check,當發(fā)現包長度超過package_max_length,將直接丟棄此數據,并關閉連接,不會占用任何內存。 // open_eof_check,因為無法事先得知數據包長度,所以收到的數據還是會保存到內存中,持續(xù)增長。 // 當發(fā)現內存占用已超過package_max_length時,將直接丟棄此數據,并關閉連接 // open_http_protocol,GET請求最大允許8K,而且無法修改配置。 // POST請求會檢測Content-Length,如果Content-Length超過package_max_length,將直接丟棄此數據,發(fā)送http 400錯誤,并關閉連接 // 此參數不宜設置過大,否則會占用很大的內存 $setConfig["package_max_length"]=2; // 啟用CPU親和性設置。在多核的硬件平臺中,啟用此特性會將swoole的reactor線程/worker進程綁定到固定的一個核上。 //可以避免進程/線程的運行時在多個核之間互相切換,提高CPU Cache的命中率。 // 使用taskset命令查看進程的CPU親和設置: // taskset -p 進程ID // pid 24666"s current affinity mask: f // pid 24901"s current affinity mask: 8 // mask是一個掩碼數字,按bit計算每bit對應一個CPU核,如果某一位為0表示綁定此核,進程會被調度到此CPU上,為0表示進程不會被調度到此CPU。 // 示例中pid為24666的進程mask = f 表示未綁定到CPU,操作系統會將此進程調度到任意一個CPU核上。 // pid為24901的進程mask = 8,8轉為二進制是 1000,表示此進程綁定在第4個CPU核上。 // 僅推薦在全異步非阻塞的Server程序中啟用 $setConfig["open_cpu_affinity"]=1; // IO密集型程序中,所有網絡中斷都是用CPU0來處理,如果網絡IO很重,CPU0負載過高會導致網絡中斷無法及時處理,那網絡收發(fā)包的能力就會下降。 // 如果不設置此選項,swoole將會使用全部CPU核,底層根據reactor_id或worker_id與CPU核數取模來設置CPU綁定。 // 如果內核與網卡有多隊列特性,網絡中斷會分布到多核,可以緩解網絡中斷的壓力 // 此選項必須與open_cpu_affinity同時設置才會生效 // array("cpu_affinity_ignore" => array(0, 1)) // 接受一個數組作為參數,array(0, 1) 表示不使用CPU0,CPU1,專門空出來處理網絡中斷。 $setConfig["cpu_affinity_ignore"]=array(0, 1); // open_tcp_nodelay // 啟用open_tcp_nodelay,開啟后TCP連接發(fā)送數據時會關閉Nagle合并算法, // 立即發(fā)往客戶端連接。在某些場景下,如http服務器,可以提升響應速度 $setConfig["open_tcp_nodelay"]=1; //啟用tcp_defer_accept特性,可以設置為一個數值,表示當一個TCP連接有數據發(fā)送時才觸發(fā)accept。 $setConfig["tcp_defer_accept"]=5; // 設置SSL隧道加密,設置值為一個文件名字符串,制定cert證書和key的路徑。 $setConfig["ssl_cert_file"]="/config/ssl.crt"; $setConfig["ssl_key_file"]="/config//ssl.key"; // 設置worker/task子進程的所屬用戶。服務器如果需要監(jiān)聽1024以下的端口, // 必須有root權限。但程序運行在root用戶下,代碼中一旦有漏洞,攻擊者就可以以root的方式執(zhí)行遠程指令,風險很大。 // 配置了user項之后,可以讓主進程運行在root權限下,子進程運行在普通用戶權限下。 // 此配置在swoole-1.7.9以上版本可用 // 僅在使用root用戶啟動時有效 $setConfig["user"]="apache"; // 設置worker/task子進程的進程用戶組。與user配置相同,此配置是修改進程所屬用戶組,提升服務器程序的安全性。 $setConfig["group"]="www-data"; // 重定向Worker進程的文件系統根目錄。此設置可以使進程對文件系統的讀寫與實際的操作系統文件系統隔離。提升安全性 $setConfig["chroot"]="/data/server/"; // 調整管道通信的內存緩存區(qū)長度。swoole的reactor線程與worker進程之間使用unix socket進行通信, // 在收發(fā)大量數據的場景下,需要啟用內存緩存隊列。此函數可以修改內存緩存的長度。 // 此參數在1.7.17以上版本默認為32M,1.7.17以下版本默認為8M $setConfig["pipe_buffer_size"]=2; // 此配置影響swoole 2個方面 // 數據發(fā)送緩存區(qū) // 調整連接發(fā)送緩存區(qū)的大小。TCP通信有擁塞控制機制,服務器向客戶端發(fā)送大量數據時,并不能立即發(fā)出。這時發(fā)送的數據會存放在服務器端的內存緩存區(qū)內。此參數可以調整內存緩存區(qū)的大小。 // 如果發(fā)送數據過多,客戶端阻塞,數據占滿緩存區(qū)后Server會報如下錯誤信息: // swFactoryProcess_finish: send failed, session#1 output buffer has been overflowed. // swoole_server->send大小 // 調用 swoole_server->send, swoole_http_server->end/write,swoole_websocket_server->push 時,最大發(fā)送的數據不得超過 buffer_output_size 配置。 // buffer_output_size默認為2M,緩存區(qū)塞滿后send將會失敗 // 注意此函數不應當調整過大,避免擁塞的數據過多,導致吃光機器內存 // 開啟大量worker進程時,將會占用worker_num * buffer_output_size 字節(jié)的內存 $setConfig["buffer_output_size"]=2;// // enable_unsafe_event // swoole在配置dispatch_mode=1或3后,因為系統無法保證onConnect/onReceive/onClose的順序,默認關閉了onConnect/onClose事件。 // 如果應用程序需要onConnect/onClose事件,并且能接受順序問題可能帶來的安全風險, //可以通過設置 enable_unsafe_event = true,啟用onConnect/onClose事件 // enable_unsafe_event配置在1.7.18以上版本可用 $setConfig["enable_unsafe_event"]=1; // swoole在配置dispatch_mode=1或3后,系統無法保證onConnect/onReceive/onClose的順序,因此可能會有一些請求數據在連接關閉后,才能到達Worker進程。 // discard_timeout_request配置默認為true,表示如果worker進程收到了已關閉連接的數據請求,將自動丟棄。 // discard_timeout_request如果設置為false,表示無論連接是否關閉Worker進程都會處理數據請求。 $setConfig["discard_timeout_request"]=1;
配置項目之后該說回調函數了,我也做了一些整理
on("Start", function (swoole_server $server){//僅允許echo、打印Log、修改進程名稱。不得執(zhí)行其他操作。 // 已創(chuàng)建了manager進程 // 已創(chuàng)建了worker子進程 // 已監(jiān)聽所有TCP/UDP端口 // 已監(jiān)聽了定時器 // 接下來要執(zhí)行 // 主Reactor開始接收事件,客戶端可以connect到Server echo PHP_EOL; echo " start"; echo PHP_EOL; var_dump($server); echo PHP_EOL; }); $serv->on("Shutdown", function (swoole_server $server){ // 在此之前Swoole Server已進行了如下操作 // 已關閉所有線程 // 已關閉所有worker進程 // 已close所有TCP/UDP監(jiān)聽端口 // 已關閉主Rector // 強制kill進程不會回調onShutdown,如kill -9 // 需要使用kill -15來發(fā)送SIGTREM信號到主進程才能按照正常的流程終止 echo PHP_EOL; echo " shutdown"; var_dump($server); echo PHP_EOL; }); $serv->on("WorkerStart", function (swoole_server $server, $worker_id){// 不能寫 int $worker_id //此事件在worker進程/task進程啟動時發(fā)生。這里創(chuàng)建的對象可以在進程生命周期內使用 echo PHP_EOL; echo " WorkerStart"; echo PHP_EOL; var_dump($worker_id); echo PHP_EOL; }); $serv->on("WorkerStop", function (swoole_server $server, int $worker_id){ //此事件在worker進程終止時發(fā)生。在此函數中可以回收worker進程申請的各類資源 // $worker_id是一個從0-$worker_num之間的數字,表示這個worker進程的ID // $worker_id和進程PID沒有任何關系 echo PHP_EOL; echo " WorkerStop"; var_dump($worker_id); echo PHP_EOL; }); //定時器觸發(fā) $serv->on("Timer", function (swoole_server $server, int $interval) { // $interval是定時器時間間隔,根據$interval的值來區(qū)分是哪個定時器觸發(fā)的。這里的定時器是由$serv->addtimer來添加的,是固定間隔循環(huán)觸發(fā)的。 // onTimer中執(zhí)行時間過長,會導致下一次定時延緩觸發(fā)。如設定1秒的定時器,1秒后會觸發(fā)onTimer,onTimer函數用時1.5s,那么第二次觸發(fā)onTimer的時間為第3秒。中間第2秒的定時器會被丟棄 // onTimer回調函數如果要執(zhí)行一個耗時操作,最好是使用$serv->task投遞到task進程池中執(zhí)行 echo PHP_EOL; echo " Timer"; var_dump($interval); echo PHP_EOL; }); $serv->on("connect",function (swoole_server $server, $fd, $from_id){ // $server是swoole_server對象 // $fd是連接的文件描述符,發(fā)送數據/關閉連接時需要此參數 // $from_id來自那個Reactor線程 // $server是swoole_server對象 // $fd是連接的文件描述符,發(fā)送數據/關閉連接時需要此參數 // $from_id來自那個Reactor線程 // onConnect/onClose這2個回調發(fā)生在worker進程內,而不是主進程。 // UDP協議下只有onReceive事件,沒有onConnect/onClose事件 echo PHP_EOL; echo " connect"; echo PHP_EOL; var_dump($fd); echo PHP_EOL; var_dump($from_id); echo PHP_EOL; }); //接收到數據時回調此函數,發(fā)生在worker進程中 $serv->on("Receive",function (swoole_server $server, $fd, $from_id, $data){ // $server,swoole_server對象 // $fd,TCP客戶端連接的文件描述符 // $from_id,TCP連接所在的Reactor線程ID // $data,收到的數據內容,可能是文本或者二進制內容 //詳情 http://wiki.swoole.com/wiki/page/50.html echo PHP_EOL; echo " Receive"; echo PHP_EOL; var_dump($fd); echo PHP_EOL; var_dump($from_id); echo PHP_EOL; var_dump($data); echo PHP_EOL; }); //接收到UDP數據包時回調此函數,發(fā)生在worker進程中。 $serv->on("Packet",function (swoole_server $server, string $data, array $client_info){ // $server,swoole_server對象 // $data,收到的數據內容,可能是文本或者二進制內容 // $client_info,客戶端信息包括address/port/server_socket 3項數據 // 服務器同時監(jiān)聽TCP/UDP端口時,收到TCP協議的數據會回調onReceive,收到UDP數據包回調onPacket echo PHP_EOL; echo " Packet"; echo PHP_EOL; var_dump($data); echo PHP_EOL; var_dump($client_info); echo PHP_EOL; }); //TCP客戶端連接關閉后,在worker進程中回調此函數 $serv->on("Close",function (swoole_server $server, int $fd, int $from_id){ // $server是swoole_server對象 // $fd是連接的文件描述符 // $from_id來自那個reactor線程 // 注意:這里回調onClose時表示客戶端連接已經關閉,所以無需執(zhí)行$server->close($fd)。代碼中執(zhí)行$serv->close($fd) 會拋出PHP錯誤告警。 echo PHP_EOL; echo " Close"; echo PHP_EOL; var_dump($fd); echo PHP_EOL; var_dump($from_id); echo PHP_EOL; }); //在task_worker進程內被調用。worker進程可以使用swoole_server_task函數向task_worker進程投遞新的任務 $serv->on("Task",function (swoole_server $serv, int $task_id, int $from_id, string $data){ // $task_id是任務ID,由swoole擴展內自動生成,用于區(qū)分不同的任務。 //$task_id和$from_id組合起來才是全局唯一的,不同的worker進程投遞的任務ID可能會有相同 // $from_id來自于哪個worker進程 // $data 是任務的內容 // 返回執(zhí)行結果到worker進程 // 1.7.2以上的版本,在onTask函數中 return字符串,表示將此內容返回給worker進程。 //worker進程中會觸發(fā)onFinish函數,表示投遞的task已完成。 echo PHP_EOL; echo " Task"; echo PHP_EOL; var_dump($task_id); echo PHP_EOL; var_dump($from_id); echo PHP_EOL; var_dump($data); echo PHP_EOL; }); //當worker進程投遞的任務在task_worker中完成時,task進程會通過swoole_server->finish()方法將任務處理的結果發(fā)送給worker進程。 $serv->on("Finish",function (swoole_server $serv, int $task_id, string $data){ // $task_id是任務的ID // $data是任務處理的結果內容 // task進程的onTask事件中沒有調用finish方法或者return結果。worker進程不會觸發(fā)onFinish echo PHP_EOL; echo " Finish"; echo PHP_EOL; var_dump($task_id); echo PHP_EOL; var_dump($data); echo PHP_EOL; }); //當工作進程收到由sendMessage發(fā)送的管道消息時會觸發(fā)onPipeMessage事件。worker/task進程都可能會觸發(fā)onPipeMessage事件 $serv->on("PipeMessage",function (swoole_server $server, int $from_worker_id, string $message){ echo PHP_EOL; echo " PipeMessage"; echo PHP_EOL; var_dump($from_worker_id); echo PHP_EOL; var_dump($message); echo PHP_EOL; }); //當worker/task_worker進程發(fā)生異常后會在Manager進程內回調此函數 $serv->on("WorkerError",function (swoole_server $serv, int $worker_id, int $worker_pid, int $exit_code){ // $worker_id是異常進程的編號 // $worker_pid是異常進程的ID // $exit_code退出的狀態(tài)碼,范圍是 1 ~255 // 此函數主要用于報警和監(jiān)控,一旦發(fā)現Worker進程異常退出, // 那么很有可能是遇到了致命錯誤或者進程CoreDump。通過記錄日志或者發(fā)送報警的信息來提示開發(fā)者進行相應的處理。 echo PHP_EOL; echo " WorkerError"; echo PHP_EOL; var_dump($from_worker_id); echo PHP_EOL; var_dump($worker_pid); echo PHP_EOL; var_dump($exit_code); echo PHP_EOL; }); //當管理進程啟動時調用它,函數原型: $serv->on("ManagerStart",function (swoole_server $serv){ // 在這個回調函數中可以修改管理進程的名稱。 // 注意manager進程中不能添加定時器 // manager進程中可以調用task功能 echo PHP_EOL; echo " ManagerStart"; echo PHP_EOL; }); //當管理進程結束時調用它,函數原型: $serv->on("ManagerStop",function (swoole_server $serv){ echo PHP_EOL; echo " ManagerStop"; echo PHP_EOL; });
呼,終于寫完了,我整理這兩個文件的目的是方便大家自己測試,官網有文檔,我做的只是代碼化。
當我把這些全部看一遍之后,我對swoole_server有了大體印象,比如worker,比如task等等。
來,上個圖
圖片看不到,看這里
http://wiki.swoole.com/wiki/page/2.html
下面開始我最喜歡的環(huán)節(jié) ,跑程序
server.php
start時會失敗 $serv = new swoole_server( $host, $port); $serv->set(array( "worker_num" => 3, //工作進程數量 )); include "OnEvent.php"; $serv->start();
client.php
on("connect", function($cli) { $cli->send("hello world "); }); $client->on("receive", function($cli, $data){ echo "Received: ".$data." "; }); $client->on("error", function($cli){ echo "Connect failed "; }); $client->on("close", function($cli){ echo "Connection close "; }); //發(fā)起網絡連接 $client->connect("127.0.0.1", 9501, 0.5);
我在server.php里引入了OnEvent.php(我寫上了所有的回調函數)
我想看看,server做了什么
來,開始
php server.php
運行結果
start object(swoole_server)#1 (4) { ["connections"]=> object(swoole_connection_iterator)#2 (0) { } ["setting"]=> array(5) { ["worker_num"]=> int(3) ["task_worker_num"]=> int(0) ["pipe_buffer_size"]=> int(33554432) ["buffer_output_size"]=> int(2097152) ["max_connection"]=> int(65536) } ["master_pid"]=> int(7418) ["manager_pid"]=> int(7420) } WorkerStart int(0) WorkerStart int(1) ManagerStart WorkerStart int(2)
程序并沒有死,上面的是回調函數里面的輸出
server先是 執(zhí)行start,然后按照設置的worker_num的數目創(chuàng)建worker觸發(fā)WorkerStart的回調,同時創(chuàng)建Manager執(zhí)行了ManagerStart
我們再看看上面的兩個圖片,結合server的運行結果,想必會更多一些了解
我覺得兩個圖畫的很好,讓我再看一遍。
好的,順便的,看到了server的屬性
object(swoole_server)#1 (4) { ["connections"]=>//看這里 http://wiki.swoole.com/wiki/page/427.html object(swoole_connection_iterator)#2 (0) { } ["setting"]=>//看這里 http://wiki.swoole.com/wiki/page/157.html array(5) { ["worker_num"]=> int(3) ["task_worker_num"]=> int(0) ["pipe_buffer_size"]=> int(33554432) ["buffer_output_size"]=> int(2097152) ["max_connection"]=> int(65536) } ["master_pid"]=>//看這里 http://wiki.swoole.com/wiki/page/154.html int(7418) ["manager_pid"]=>//看這里 http://wiki.swoole.com/wiki/page/155.html int(7420) }
因為配置的沒寫task,并且當前沒有客戶端連上來,這里還有一些屬性沒有展示出來
大家詳細的看這里 屬性列表
好的,讓我們運行客戶端
php client.php
connect int(1) // 這個是 fd int(0)// 這個是 from_id Receive int(1)// 這個是 fd int(0)// 這個是 from_id string(12) "hello world "http:// 這個是 data
這里貼出來 server端多出來的內容
補充一下:對一個對象使用get_class_methods可以獲得對象的所有方法,今天忘了怎么獲取客戶端ip地址了,用這個查了一下,是server的connection_info方法
好的,希望大家用多測試測試,觀察server的變化,體會swoole的server調用
結合運行結果來看流程圖
今天暫時到這里,哪里我說的不對,請大家指正,我也是一個學習中的人
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21078.html
摘要:初始化發(fā)送消息判斷用戶是否登錄如果沒有登錄拒絕連接斷開清除信息處理協議主要是方法,輪訓獲取消息。 這個列子主要討論Tcp,WebSocket和http之間的通訊。長連接和長連接通訊,長連接和短連接通訊。其他協議同理可得 Tcp: 代表硬件設備 WebSocket: 代表客戶端 http: 代表網頁 本列子是基于one框架 (https://github.com/lizhicha...
摘要:單進程讀寫性能可達萬,不同的進程使用不同的管道通信,可以最大化利用多核。但這任務如果是調用程序接口時,由于網絡的延遲,增加的任務大于消費的任務時,內存占用會不斷的增加,導致服務器的內存被占滿。 應用場景簡介 與硬件設備連接通訊(定位設備) IM系統(用于直播頁面的聊天通訊) 場景1 - 實時收集定位數據實時輸出(例 滴滴司機行駛軌跡) 說明:需要將所有的定位設備實時的接收,將實時的...
閱讀 2310·2021-11-22 12:01
閱讀 1983·2021-11-12 10:34
閱讀 4509·2021-09-22 15:47
閱讀 2827·2019-08-30 15:56
閱讀 2861·2019-08-30 15:53
閱讀 2398·2019-08-30 13:53
閱讀 3371·2019-08-29 15:35
閱讀 3119·2019-08-29 12:27