最近使用swoole做websocket服务器,利用yii的command来启动服务,发现swoole始终不响应onClose事件,始终找不到原因,我尝试直接使用官方例子来运行websocket服务,却可以正常触发onClose事件,通过仔细对比跟官方例程的区别,最后发现原来是这东西引起的:
dispatch_mode=3
如果dispatch_mode为3的话,onClose就会失效,
贴一段官方的文档:
dispatch_mode
数据包分发策略。可以选择7种类型,默认为2
1,轮循模式,收到会轮循分配给每一个Worker进程
2,固定模式,根据连接的文件描述符分配Worker。这样可以保证同一个连接发来的数据只会被同一个Worker处理
3,抢占模式,主进程会根据Worker的忙闲状态选择投递,只会投递给处于闲置状态的Worker
4,IP分配,根据客户端IP进行取模hash,分配给一个固定的Worker进程。可以保证同一个来源IP的连接数据总会被分配到同一个Worker进程。算法为 ip2long(ClientIP) % worker_num
5,UID分配,需要用户代码中调用 Server->bind() 将一个连接绑定1个uid。然后底层根据UID的值分配到不同的Worker进程。算法为 UID % worker_num,如果需要使用字符串作为UID,可以使用crc32(UID_STRING)
7,stream模式,空闲的Worker会accept连接,并接受Reactor的新请求
下面最关键的还有一段话:
dispatch_mode 4,5两种模式,在1.7.8以上版本可用
dispatch_mode=1/3时,底层会屏蔽onConnect/onClose事件,原因是这2种模式下无法保证onConnect/onClose/onReceive的顺序
非请求响应式的服务器程序,请不要使用模式1或3