You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:52:46