tp5.1 的think-swoole文档写的太简单了,使用时需要花费点时间研究。
先说说配置吧!当你按tp5.1文档在swoole_server.php中配置了swoole_class后,swoole_server中的其他配置将无效,需要在swoole_class对应的类中配置相应参数。
图2配置示例:
protected $serverType = 'socket'; 这个一定要加上,否则就是httpserver ,我之前在这里配置不对,websocket怎么都连接不上,因为默认启动的是httpserver。
配置完后,再说说swoole中的table如何使用吧!tp5.1手册中并没有相关用法,通过搜到的内容我先是将swoole table初始化放到了OnWorkStart事件中,这表面看没啥问题,好像也能使用,实际上是错误的用法。
swoole若开启多个进程,在工作进程内定义的table,在其他进程是无效的。实践时发现无法读取到table中的内容,开始以为业务代码有问题,调试后发现内容为空,这是错误的用法。通过查看swoole文档了解table必须要在swoole启动前创建并加入到swoole服务对象中才可以在多进程中共享使用,启动后的进程是相互独立的内存空间。
查看think-swoole server.php源码时发现要在启动前创建table的话,正好可在方法init()中创建。
那么在前面图2的swoole服务类中重载父类的init方法创建table并加入到swoole服务对象中,实践发现可成功读取到创建的任意table中的数据。
示例:
最后说说在think-swoole中使用数据库的问题,直接在业务代码中使用的think\Db,开始没发现什么问题。后来发现有时涉及到db的操作时,会报错mysql has gone away。通过搜索发现是这么说的:
多进程如果共用1个连接,那么返回的结果无法保证被哪个进程处理。持有连接的进程理论上都可以对这个连接进行读写,这样数据就发生错乱了。一个进程对连接的关闭,也造成了其他进程对该连接的丢失,导致了玄学的 mysql has gone away错误。
如何解决呢,看网络上有个办法是每个进程中(onWorkStart中)都创建一个数据库连接去操作数据库,更优的办法应该是直接使用数据库连接池了。
比如 swoole-orm 这个包是基于swoole mysql协程数据库连接池。db是参考thinkphp-orm的,所以db操作与tp类似。