首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
HTTP请求回调中,如何通过类似于信号量同步的方式阻塞等待数据处理后,再返回响应?
### 问题描述 目前的场景:调用者A通过HTTP请求onRequest回调进入到swoole,处理请求的过程中,将数据通过WebSocket发送给客户端B。 客户端B处理数据后通过WebSocket返回响应通过onMessage回调传给swoole。最后swoole将数据响应给客户端A。 整个过程中调用者A处于阻塞状态等待客户端B的数据。并设置一个超时时间,如果超时未响应,则直接推送错误信息给调用者A。 ### 目前的处理方案 调用者A的Http请求进入,并通过WebSocket推送给客户端B时,对调用者A创建了一个Redis轮询,直到当WebSocket收到数据后,将结果写入redis。 ### 期待的方案 是否存在特性,可以不使用轮询的方式,而是使用类似于线程间同步的阻塞方法,比如Python的event.wait()。让onRequest回调流程阻塞,当onMessage收到消息后,可以有选择的发送信号量通知给指定的onRequest,并且支持超时机制。 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole ver : 4.8.10 OS : CentOS 7 php : 7.3.28
发布于3年前 · 10 次浏览 · 来自
提问
Hermit小新
### 问题描述 目前的场景:调用者A通过HTTP请求onRequest回调进入到swoole,处理请求的过程中,将数据通过WebSocket发送给客户端B。 客户端B处理数据后通过WebSocket返回响应通过onMessage回调传给swoole。最后swoole将数据响应给客户端A。 整个过程中调用者A处于阻塞状态等待客户端B的数据。并设置一个超时时间,如果超时未响应,则直接推送错误信息给调用者A。 ### 目前的处理方案 调用者A的Http请求进入,并通过WebSocket推送给客户端B时,对调用者A创建了一个Redis轮询,直到当WebSocket收到数据后,将结果写入redis。 ### 期待的方案 是否存在特性,可以不使用轮询的方式,而是使用类似于线程间同步的阻塞方法,比如Python的event.wait()。让onRequest回调流程阻塞,当onMessage收到消息后,可以有选择的发送信号量通知给指定的onRequest,并且支持超时机制。 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole ver : 4.8.10 OS : CentOS 7 php : 7.3.28
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2022-10-27
Rango
这个可以用协程的 `Channel` 来实现。需要等待的地方就使用`Channel::pop()`,多个协程可以传递消息,来实现依赖管理。
赞
1
回复
2022-10-27
Hermit小新
回复
Rango
您好,感谢您的回复,测试发现:由于WebSocket `onMessage`的处理`Worker` 与Http请求的发送者所在的`Worker`不同,导致他俩不在同一个进程,`Channel`能否在这种情况下实现不同进程间的协程间通讯吗? 如果不能的话,还有其他支持阻塞、超时的替代方案吗?
赞
1
回复
2022-10-28
Hermit小新
回复
Rango
经测试,采用了有名管道`Pipe`并结合`waitEvent`来实现不同进程、协程见的数据交互、阻塞、超时特性,可以满足上述需求。 问题1、您看看除了这个方案之外,是否有更好的推荐实现方案? 问题2、当使用协程版本的`fwrite`和`fread`后,会有如下log输出: ``` [trigger][notice]:[Function Swoole\Coroutine\System::fread() is deprecated at file://xx.php line:80] [trigger][notice]:[Function Swoole\Coroutine\System::fwrite() is deprecated at file:file://xx.php line:23] ``` 使用php原生的`fread`和`fwrite`则不会有上述提示。请教一下为什么不建议使用携程版本的`fread`和`fwrite`?
赞
1
回复