为了测试我正在编写的R包的网络功能,我尝试使用httpuv
包在本地提供文件,以便我可以使用页面的脱机副本运行测试。 / p>
但是,curl
似乎并不想与httpuv
配合使用-特别是在尝试使用curl
(例如,与{{1} }或curl::curl()
),请求将挂起,如果不手动中断,最终将超时。
curl::curl_fetch_memory()
服务器启动后,在终端上运行# Serve a small page
server <- httpuv::startServer("0.0.0.0", port = 9359, app = list(
call = function(req) {
list(
status = 200L,
headers = list("Content-Type" = "text/html"),
body = "Some content..."
)
}
))
# Attempt to retrieve content (this hangs)
page <- curl::curl_fetch_memory(url = "http://127.0.0.1:9359")
httpuv::stopServer(server)
将按预期返回内容。另外,如果我打开一个RStudio的新实例并尝试在该新的R会话中curl -v 127.0.0.1:9359
(而旧的R会话仍处于打开状态),则它可以正常工作。
受此鼓舞,我已经和curl::curl_fetch_memory()
玩了一段时间,以为也许可以在某些后台进程中启动服务器,然后照常继续。不幸的是,到目前为止,这种方法还没有成功。
任何见解或建议都非常感谢!
答案 0 :(得分:0)
当您回来回答您提出的问题时,感觉不是很好!
摘自httpuv::startServer()
文档:
startServer绑定指定的端口,并在后台运行的线程上侦听连接。此后台线程处理I / O,并且在收到HTTP请求时,将调度对应用程序中用户定义的R函数的调用以处理该请求。此调度是使用Later()完成的。当R调用堆栈为空时-换句话说,当交互式R会话在命令提示符处处于空闲状态时-R将自动运行计划的调用。但是,如果调用堆栈不为空(如果R正在评估其他R代码),则在调用堆栈为空或调用run_now()函数之前,将不会执行回调。该函数告诉R执行由Later()安排的任何回调。 service()函数本质上是run_now()的包装。
换句话说,如果我们想在收到请求后立即对其进行响应,则必须使用httpuv::service()
来明确地响应。类似于以下内容的技巧!
s <- callr::r_session$new()
on.exit(s$close())
s$call(function() {
httpuv::startServer("0.0.0.0", port = 9359, app = list(
call = function(req) {
list(
status = 200L,
headers = list("Content-Type" = "text/html"),
body = "Some content...")
)
}
))
while (TRUE) httpuv::service()
})
# Give the server a chance to start
Sys.sleep(3)
page <- curl_fetch_memory(url = "http://127.0.0.1:9359")