swoole的TCP服务器实现-swoole_server创建过程

这里只介绍源码实现,如果对于的了解和使用,请参考官方网站:,这里感谢开源,有这些优秀的产品大家可以尽情的学习 。要看的实现,需要下载的代码,下载地址为:下载解压后,可以导入到cdt或者-去阅读,本系列文章基于 4.0.3分享,我用的代码阅工具为-cdt,我的代码放置路径为:E:\-src-
因是PHP扩展,在看代码时,会插入一些PHP扩展实现的API介绍,后面我会写一篇PHP扩展相关的文章,来总结下里面用到的扩展API 。
下载代码后导入后的目录图如下(编辑器导入后,一屏幕截图不了,这里贴的是下展示) 。

swoole的TCP服务器实现-swoole_server创建过程

文章插图
现在结合官网提供出来的Demo做分享,下面代码就是Demo里TCP-的实例 。
//创建Server对象,监听 127.0.0.1:9501端口$serv = new swoole_server("127.0.0.1", 9501); //监听连接进入事件$serv->on('connect', function ($serv, $fd) {echo "Client: Connect.\n";});//监听数据接收事件$serv->on('receive', function ($serv, $fd, $from_id, $data) {$serv->send($fd, "Server: ".$data);});//监听连接关闭事件$serv->on('close', function ($serv, $fd) {echo "Client: Close.\n";});//启动服务器$serv->start();
swoole的TCP服务器实现-swoole_server创建过程

文章插图
第一行代码,首先是定义的对象,传入了两个参数,其中一个参数是服务器的IP地址,为字符串类型,另外一个是服务器的端口信息,为整型信息,而在官方文档中可以找到,的完整的构造函数如下:
$serv = new swoole_server(string $host, int $port = 0, int $mode = SWOOLE_PROCESS,int $sock_type = SWOOLE_SOCK_TCP);
也就是mode和是有默认值的,mode代表的进程模式,这里默认为多进程,为服务器类型,这里默认为TCP类型的,关于的完整定义的说明可以参考官方文档:
在扩展代码中找到这个相关的定义,这个还是很好找,具体路径为:E:\-src-\.c,也就是在代码根目录下 。因现在是个对象,按PHP扩展的API,那在PHP扩展的实现中肯定是通过的方式去实现,且对应到现在的例子,完整的函数名定义为:
PHP_METHOD(swoole_server, __construct)
在-.c文件中,通过编辑器的搜索即可找到其完整的实现,我的编辑器中是从1910行开始,如下图所示:
swoole的TCP服务器实现-swoole_server创建过程

文章插图
【swoole的TCP服务器实现-swoole_server创建过程】该方法完整的代码如下:
PHP_METHOD(swoole_server, __construct){zend_size_t host_len = 0;//用于后续获取服务器IP地址信息时,存在IP地址长度信息char *serv_host;//获取服务器的IP地址信息,类型为字符串,构造PHP的swoole_server对象时传入,必传long sock_type = SW_SOCK_TCP;//server对应的Socket类型,构造PHP的swoole_server对象时传入,可选long serv_port = 0;//用于存放服务器端口信息,构造PHP的swoole_server对象时传入,必传long serv_mode = SW_MODE_PROCESS;//server的运行方式,构造PHP的swoole_server对象时传入,必传//only cli env,这里sapi_module是PHP内部实现的模块名,这里判断swoole_server只能运行在cli模式下,否则启动失败,sapi_module.name为PHP运行方式,也就是说swoole_server不能运行在fast-cgi模式下 。if (strcasecmp("cli", sapi_module.name) != 0){swoole_php_fatal_error(E_ERROR, "swoole_server only can be used in PHP CLI mode.");RETURN_FALSE;}//swoole的主事件模块已经启动,不运行重复启动,SwooleG这个模块的初始化和设置值,在后面的逻辑中,暂时先分析到这里,后面具体分析 。if (SwooleG.main_reactor != NULL){swoole_php_fatal_error(E_ERROR, "eventLoop has already been created. unable to create swoole_server.");RETURN_FALSE;}//一个PHP程序只能启动一个swoole_server,SwooleG这个模块的初始化和设置值,在后面的逻辑中,暂时先分析到这里,后面具体分析 。if (SwooleG.serv != NULL){swoole_php_fatal_error(E_WARNING, "server is running. unable to create swoole_server.");RETURN_FALSE;}//swServer是PHP的swoole_server对象的一个抽象,通过sw_malloc申请内存空间,其实sw_malloc的实现就是c的malloc申请空间的 。swServer *serv = sw_malloc(sizeof (swServer));//swServer模块的初始化,请看下面单独的分析 。swServer_init(serv);//PHP扩展的API,用于从PHP层获取输入参数信息,这里总共获取了serv_host,serv_port,serv_mode,sock_type信息if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lll", &serv_host, &host_len, &serv_port, &serv_mode, &sock_type) == FAILURE){swoole_php_fatal_error(E_ERROR, "invalid swoole_server parameters.");return;}//如果是windows环境下,serv_mode取值为SW_MODE_SINGLE(单进程)模式,具体的后续再分析#ifdef __CYGWIN__serv_mode = SW_MODE_SINGLE;#elif !defined(SW_USE_THREAD)//当前不支持多线程模式//如果server的模式为SW_MODE_THREAD 和 SW_MODE_BASE 模式,则调整为SW_MODE_SINGLE(单进程)模式if (serv_mode == SW_MODE_THREAD || serv_mode == SW_MODE_BASE){serv_mode = SW_MODE_SINGLE;swoole_php_fatal_error(E_WARNING, "can't use multi-threading in PHP. reset server mode to be SWOOLE_MODE_BASE");}#endif//serv用factory_mode属性保存serv_mode值serv->factory_mode = serv_mode;//如果server为单进程模式,则worker进程个数设置为1,且max_request为0,也就是从不退出,因为退出后,就没有worker进程服务了 。if (serv->factory_mode == SW_MODE_SINGLE){serv->worker_num = 1;//worker进程个数serv->max_request = 0;}//全局变量php_sw_server_callbacks的初始,这个表示回调函数指针bzero(php_sw_server_callbacks, sizeof (zval*) * PHP_SERVER_CALLBACK_NUM);if (serv_port == 0 && strcasecmp(serv_host, "SYSTEMD") == 0)//如果server对于的端口号为0,且主机名为SYSTEMD,这种场景比较少见{if (swserver_add_systemd_socket(serv)