我写的这个Demo项目 https://github.com/ligaofeng/hyperf-socket-chat 在启动后,访问以下两个页面:
模拟uid为1的在房间1的Demo样例: http://127.0.0.1:9501/view/socket1
模拟uid为2的在房间1的Demo样例: http://127.0.0.1:9501/view/socket2
会触发以下BUG:
PHP Fatal error: Uncaught Swoole\Error: Socket#99 has already been bound to another coroutine#2, reading of the same socket in coroutine#3 at the same time is not allowed in /Users/mac/www/ktalk/vendor/hyperf/redis/src/RedisConnection.php:67
Stack trace:
#0 /Users/mac/www/ktalk/vendor/hyperf/redis/src/RedisConnection.php(67): Redis->multi()
#1 /Users/mac/www/ktalk/vendor/hyperf/redis/src/Redis.php(49): Hyperf\Redis\RedisConnection->__call()
#2 /Users/mac/www/ktalk/vendor/hyperf/redis/src/RedisProxy.php(32): Hyperf\Redis\Redis->__call()
#3 /Users/mac/www/ktalk/vendor/hyperf/socketio-server/src/Room/RedisAdapter.php(69): Hyperf\Redis\RedisProxy->__call()
#4 /Users/mac/www/ktalk/vendor/hyperf/socketio-server/src/Socket.php(70): Hyperf\SocketIOServer\Room\RedisAdapter->add()
#5 /Users/mac/www/ktalk/runtime/container/proxy/App_Controller_WebSocketController.proxy.php(100): Hyperf\SocketIOServer\Socket->join()
#6 /Users/mac/www/ktalk/runtime/container/proxy/App_Controller_WebSocketController.proxy.php(69): App\Controller\WebSocketC in /Users/mac/www/ktalk/vendor/hyperf/redis/src/RedisConnection.php on line 67
有时启动hyperf后,即使是不访问这两个页面也会报,且报的时机和时间不固定,且不是必现的,一般启动运行一会后会出现,目前确认不是由于代码上写法有误导致的,也不是swoole官方文档上说的可能会有这种写法的问题(https://wiki.swoole.com/wiki/page/963.html),且我和我同事的MAC环境上都复现了,hyperf核心开发人员之一李铭昕也在他的MAC环境上也复现了,我的MAC环境:PHP版本:7.4.10,swoole扩展版本:4.5.3,redis扩展版本:5.3.1。
初步怀疑是hyperf/async-queue库与Redis 协程客户端库hyperf/redis,在开发socket.io相关功能时不兼容,目前已经在github上提交了issue,issue地址为:https://github.com/hyperf/hyperf/issues/2581
坐等hyperf官方修复此BUG....