R是否有类似Python asyncio.sleep()的非阻塞等待函数?
解决R中WebSocket心跳的非阻塞等待问题
R里有多种非阻塞等待的实现方案,核心思路是通过事件驱动或异步调度替代阻塞式的Sys.sleep(),既能定期发送Discord心跳,又不影响WebSocket接收消息。
方案1:用processx的poll()实现非阻塞监听
processx的poll()函数可以在指定超时时间内监听WebSocket连接的事件,期间不会阻塞进程,同时能处理 incoming 消息,还能触发心跳逻辑。
示例代码:
library(processx) library(websocket) # 初始化WebSocket连接 ws <- websocket::WebSocket$new("wss://your-discord-gateway-url") # Discord标准心跳消息示例 JsonKeepAliveMessage <- '{"op": 1, "d": null}' last_heartbeat <- Sys.time() # 设置消息接收回调 ws$onMessage(function(event) { cat("收到消息:", event$data, "\n") }) # 主循环 while(TRUE) { # 检查是否需要发送心跳 if(as.numeric(Sys.time() - last_heartbeat) >= 40) { ws$send(JsonKeepAliveMessage) last_heartbeat <- Sys.time() cat("发送心跳\n") } # 非阻塞等待1秒,同时监听WebSocket连接(timeout单位为毫秒) poll(list(ws$getSocket()), timeout = 1000) }
方案2:用later包实现异步定时心跳
later包支持异步定时任务调度,能在指定延迟后执行心跳函数,完全不阻塞WebSocket的消息处理流程。
示例代码:
library(later) library(websocket) ws <- websocket::WebSocket$new("wss://your-discord-gateway-url") JsonKeepAliveMessage <- '{"op": 1, "d": null}' # 定义心跳函数,发送后自动调度下一次 send_heartbeat <- function() { ws$send(JsonKeepAliveMessage) cat("发送心跳\n") # 40秒后再次执行心跳 later(send_heartbeat, delay = 40) } # 设置消息接收回调 ws$onMessage(function(event) { cat("收到消息:", event$data, "\n") }) # 启动第一次心跳调度 later(send_heartbeat, delay = 40) # 维持事件循环,处理异步任务和消息 while(TRUE) { run_now() # 处理待执行的异步任务 Sys.sleep(0.1) # 短时间低延迟阻塞,避免CPU空转 }
注意事项
- 避免无阻塞的空循环(无任何睡眠),会导致CPU占用率拉满;短时间的低延迟阻塞(如
Sys.sleep(0.1))对消息接收几乎无影响,还能有效降低负载。 - 两种方案都能保证WebSocket正常接收消息的同时,按时发送心跳维持Discord连接。
内容的提问来源于stack exchange,提问作者Camilo
相关产品推荐
相关产品推荐

