WorkerMan源碼分析 - 實現最簡單的原型


之前一直認為workerman源碼理解起很復雜,這段時間花了3個下午研究,其實只要理解 php如何守護化進程、信號、多進程、libevent擴展使用,對於如何實現就比較輕松了。

相關代碼都在github地址里,具體注釋都有。

守護化進程:
http://www.cnblogs.com/loveyouyou616/p/7867132.html
http://www.cnblogs.com/loveyouyou616/p/8881531.html
https://github.com/zhaocong222/workerman-learn/tree/master/test/daemon

信號與多進程:
http://www.cnblogs.com/loveyouyou616/p/8854835.html
https://github.com/zhaocong222/workerman-learn/tree/master/test/signal%26%26fork

libevent擴展使用:
https://github.com/zhaocong222/workerman-learn/tree/master/test/libevnt

以下為workerman讀取socket數據的最簡原型
<?php
$eventBase = new EventBase();
$arr = [];

function add($fd,$func){

    global $arr,$eventBase;
    $event = new Event($eventBase, $fd, Event::READ | Event::PERSIST, $func, $fd);

    if (!$event||!$event->add()) {
        return false;
    }

    //關鍵點1
    $arr[posix_getpid()][] = $event;
}
function baseRead($socket){
    $buffer = @fread($socket, 2);
    echo $buffer."\n";
}

function acceptConnection($socket){

    $new_socket = @stream_socket_accept($socket, 0);
    // Thundering herd.
    if (!$new_socket) {
        return;
    }

    stream_set_blocking($new_socket, 0);
    //關鍵點2
    stream_set_read_buffer($new_socket, 0);

    add($new_socket,'baseRead');
}

$socketmain = stream_socket_server('tcp://127.0.0.1:4455', $errno, $errmsg, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
//非阻塞
stream_set_blocking($socketmain,0);

add($socketmain,'acceptConnection');

$eventBase->loop();

重點,重點,重點

ps: 這里需要注意2點,我就是在這2點琢磨了好久。

1. event實例一定要存放在一個全局數組里面 (應該是出了函數作用域就銷毀了)

2. 如果fwrite的數據要大於 fread 設置的大小,要加上  stream_set_read_buffer($new_socket, 0);   讀取stream時需要設置為無緩沖區

通過telnet來設置:

服務端打印的數據如下:

通過上面的代碼 結合 信號 以及多進程 最后就是workerman的核心部分。

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM