swoole的server使用其他异步api为啥一定要在onWorkerStart中使用

因为swoole就是这样设计的,资源的创建和初始化应该放在worker进程中做,onWorkerStart是worker进程的入口,也是你的代码的最早的入口。如果你用框架,框架也应当在onWorkerStart中完成初始化。假如你不在worker进程中做了资源创建,例如你创建了一个socket连接,那么在fork之后,会有多个worker进程共享这个socket,大家都去读写这个socket会带来很多同步问题,在master进程中创建资源,绝大部分时候只有弊端没有收益,所以不要轻易这么做,除非你充分权衡过这么做的利弊。
eventloop不能重复创建这个报错,也是设计使然,其实也可以设计成不报错,自动attach到已经创建的eventloop中去,像Go语言的eventloop对开发者是透明的,它会自动创建和管理,完全不需要使用者对它有概念。这只是种选择,不同做法各有利弊,你选择了某个库,最好顺着库的设计思路走,可以少一些不必要的麻烦。

■网友
https://wiki.swoole.com/wiki/page/780.html文档说得很清楚了,因为异步IO客户端已经创建了事件循环EventLoop,导致swoole_server无法创建,自然也就出错了.而worker进程内置有EventLoop,能供各种异步IO客户端使用.开发者编写的大多数PHP逻辑代码,就跑在worker进程里.比如除了workerstart事件的回调函数,还有HTTP的request,WebSocket的open/message,TCP的connect/receive/close等回调函数.
另外,就算是没有EventLoop的同步IO客户端,也不应该在swoole_server前创建,因为多个worker进程共享一个Redis或MySQL客户端可能发生读写错乱的问题.
https://wiki.swoole.com/wiki/page/325.html
■网友
首先看看是哪里抛出的致命错误
./swoole_server.c:1620PHP_METHOD(swoole_server, __construct){.....if (SwooleG.main_reactor != NULL) { swoole_php_fatal_error(E_ERROR, "eventLoop has already been created. unable to create swoole_server."); RETURN_FALSE; }......}很明显就是因为 SwooleG.main_reactor 在之前赋值了.所以才抛出错误
然后看WebSocketClient 是在哪里赋值的:
./tests/include/api/swoole_websocket_server/websocket_client.php //WebSocketClient 的 第60行的connect 函数 $this-\u0026gt;socket = new \\swoole_client(SWOOLE_SOCK_TCP);所以WebSocket是基于swoole_client。实现的,而swoole_client的构造函数 会调用 php_swoole_check_reactor
./swoole_client.cstatic PHP_METHOD(swoole_client, __construct){...... php_swoole_check_reactor();......}看一下php_swoole_check_reactor 这个函数
./swoole_client.cvoid php_swoole_check_reactor(){....... if (SwooleG.main_reactor == NULL){........ SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); } }} 【swoole的server使用其他异步api为啥一定要在onWorkerStart中使用】 所以server会抛出致命错误


    推荐阅读