首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
执行Redis订阅后,无法执行其他操作了
### 问题描述 执行Redis订阅后,无法执行其他操作了 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole-4.5.7 php-7.4.12 CentOS 8 ### 相关代码 ```php <?php error_reporting(0); if (php_sapi_name() !== 'cli') { die(); } $a = swoole_get_local_ip(); $ip = $a['ens32'] ? $a['ens32'] : $a['eth0']; try { $server = new Swoole\WebSocket\Server($ip, 843, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); } catch (Exception $e) { echo $e->getMessage(); die(); } $GLOBALS['server'] = $server; $server->set([ 'daemonize' => false, 'pid_file' => '/tmp/qot_websocket_server1.pid', 'log_file' => '/tmp/qot_websocket_server1.log', 'worker_num' => 1, 'ssl_cert_file' => __DIR__ . '/../config/fullchain.pem', 'ssl_key_file' => __DIR__ . '/../config/privkey.pem' ]); $server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) { $GLOBALS["fd"] = $request->fd; $redis = new Redis(); $redis->connect('/tmp/redis.sock'); $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); $redis->subscribe(['order'], function ($redis, $chan, $msg) { var_dump($redis); var_dump($chan); var_dump($msg); $GLOBALS['server']->push($GLOBALS["fd"], $msg); }); }); $server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) { echo 'OK'; //客户端发消息过来,不会输出 }); $server->on('close', function (Swoole\WebSocket\Server $server, $fd, $reactorId) {}); $server->start(); ``` ### 你期待的结果是什么?实际看到的错误信息又是什么? 期待echo 'OK';被执行,实际未被执行 另外请看下$GLOBAL是不是这么用的
发布于5年前 · 7 次浏览 · 来自
提问
hkargv
### 问题描述 执行Redis订阅后,无法执行其他操作了 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole-4.5.7 php-7.4.12 CentOS 8 ### 相关代码 ```php <?php error_reporting(0); if (php_sapi_name() !== 'cli') { die(); } $a = swoole_get_local_ip(); $ip = $a['ens32'] ? $a['ens32'] : $a['eth0']; try { $server = new Swoole\WebSocket\Server($ip, 843, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); } catch (Exception $e) { echo $e->getMessage(); die(); } $GLOBALS['server'] = $server; $server->set([ 'daemonize' => false, 'pid_file' => '/tmp/qot_websocket_server1.pid', 'log_file' => '/tmp/qot_websocket_server1.log', 'worker_num' => 1, 'ssl_cert_file' => __DIR__ . '/../config/fullchain.pem', 'ssl_key_file' => __DIR__ . '/../config/privkey.pem' ]); $server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) { $GLOBALS["fd"] = $request->fd; $redis = new Redis(); $redis->connect('/tmp/redis.sock'); $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); $redis->subscribe(['order'], function ($redis, $chan, $msg) { var_dump($redis); var_dump($chan); var_dump($msg); $GLOBALS['server']->push($GLOBALS["fd"], $msg); }); }); $server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) { echo 'OK'; //客户端发消息过来,不会输出 }); $server->on('close', function (Swoole\WebSocket\Server $server, $fd, $reactorId) {}); $server->start(); ``` ### 你期待的结果是什么?实际看到的错误信息又是什么? 期待echo 'OK';被执行,实际未被执行 另外请看下$GLOBAL是不是这么用的
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2020-11-18
鲁飞
subscribe 把进程阻塞了,所以不会没有走到onmessage。 你这里可以用use,而不是GLOBAL ```php $redis->subscribe(['order'], function ($redis, $chan, $msg) use ($server, $request) { var_dump($redis); var_dump($chan); var_dump($msg); $server->push($request->fd, $msg); }); ```
赞
2
回复
2020-11-18
hkargv
谢谢指导 我想让它非阻塞 以前是用异步客户端可以做到,现在协程怎么让它做到呢?
赞
0
回复
2020-11-18
鲁飞
回复
hkargv
使用自定义进程处理 https://wiki.swoole.com/#/server/methods?id=addprocess
赞
1
回复
2021-09-16
Shenhai
回复
鲁飞
貌似这个场景不适合自定义进程,我看文档里创建自定义进程需要在$server->start()前执行$server->addProcess()方法,而代码中创建Redis订阅是在open事件中,在open中addProcess()应该会报错吧 `PHP Fatal error: Uncaught ErrorException: Swoole\Server::addProcess(): server is running, can't add process in`
赞
0
回复
2020-11-18
hkargv
```php <?php error_reporting(0); if (php_sapi_name() !== 'cli') { die(); } $a = swoole_get_local_ip(); $ip = $a['ens32'] ? $a['ens32'] : $a['eth0']; Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]); try { $server = new Swoole\WebSocket\Server($ip, 843, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); } catch (Exception $e) { echo $e->getMessage(); die(); } $server->set([ 'daemonize' => false, 'pid_file' => '/tmp/qot_websocket_server1.pid', 'log_file' => '/tmp/qot_websocket_server1.log', 'worker_num' => 1, 'ssl_cert_file' => __DIR__ . '/../config/fullchain.pem', 'ssl_key_file' => __DIR__ . '/../config/privkey.pem' ]); $server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) { $redis = new Redis(); $redis->connect('/tmp/redis.sock'); $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); $redis->subscribe(['order'], function ($redis, $chan, $msg) use ($server, $request) { var_dump($redis); var_dump($chan); var_dump($msg); $server->push($request->fd, $msg); }); }); $server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) { echo 'OK'; //客户端发消息过来,正常输出 }); $server->on('close', function (Swoole\WebSocket\Server $server, $fd, $reactorId) {}); $server->start(); ``` 今天深入学习了一下协程,发现有一个 一键协程 功能 于是在第十行加入: Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]); 发现不堵塞了,我用这个实现是否是正确的?谢谢
赞
0
回复
2020-11-18
鲁飞
回复
hkargv
嗯
赞
0
回复