WorkerMan源码分析 - 实现最简单的原型

Posted 睡着的糖葫芦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的核心部分。


以上是关于WorkerMan源码分析 - 实现最简单的原型的主要内容,如果未能解决你的问题,请参考以下文章

WorkerMan源码分析(resetStd方法,PHP中STDIN, STDOUT, STDERR的重定向)

F2 workerman 整合入项目

workerman实现简单弹幕的方法

Spring源码分析原型Bean实例化过程byName与byType及FactoryBean获取Bean源码实现

使用workerman实现在线聊天-第一版

F11 workerman 聊天列表初始化之数据获取长连接下实现聊天列表实时更新完结