在 R 会话中访问本地提供的文件
Access locally served files within an R session
上下文
为了测试我正在编写的 R 包的 Web 功能,我尝试使用 httpuv
包在本地提供文件,以便我可以 运行 使用离线测试页面副本。
问题
然而,curl
似乎并不想与 httpuv
一起玩得很好——具体来说,当尝试使用 curl
读取托管文件时(例如,使用 curl::curl()
or 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)
当前进度
服务器启动后,运行在终端 returns 将 curl -v 127.0.0.1:9359
内容按预期显示。此外,如果我打开一个 RStudio 的新实例并尝试 curl::curl_fetch_memory()
在那个新的 R 会话中(而旧的仍然打开),它工作得很好。
受此鼓舞,我一直在研究 callr
一段时间,认为也许可以在某些后台进程中启动服务器,然后照常继续。不幸的是,到目前为止我还没有用这种方法取得任何成功。
非常感谢任何见解或建议!
当你能回来回答你提出的问题时,是不是感觉很棒!
来自 httpuv::startServer()
文档:
startServer binds the specified port and listens for connections on an thread running in the background. This background thread handles the I/O, and when it receives a HTTP request, it will schedule a call to the user-defined R functions in app to handle the request. This scheduling is done with later(). When the R call stack is empty – in other words, when an interactive R session is sitting idle at the command prompt – R will automatically run the scheduled calls. However, if the call stack is not empty – if R is evaluating other R code – then the callbacks will not execute until either the call stack is empty, or the run_now() function is called. This function tells R to execute any callbacks that have been scheduled by later(). The service() function is essentially a wrapper for 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")
上下文
为了测试我正在编写的 R 包的 Web 功能,我尝试使用 httpuv
包在本地提供文件,以便我可以 运行 使用离线测试页面副本。
问题
然而,curl
似乎并不想与 httpuv
一起玩得很好——具体来说,当尝试使用 curl
读取托管文件时(例如,使用 curl::curl()
or 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)
当前进度
服务器启动后,运行在终端 returns 将 curl -v 127.0.0.1:9359
内容按预期显示。此外,如果我打开一个 RStudio 的新实例并尝试 curl::curl_fetch_memory()
在那个新的 R 会话中(而旧的仍然打开),它工作得很好。
受此鼓舞,我一直在研究 callr
一段时间,认为也许可以在某些后台进程中启动服务器,然后照常继续。不幸的是,到目前为止我还没有用这种方法取得任何成功。
非常感谢任何见解或建议!
当你能回来回答你提出的问题时,是不是感觉很棒!
来自 httpuv::startServer()
文档:
startServer binds the specified port and listens for connections on an thread running in the background. This background thread handles the I/O, and when it receives a HTTP request, it will schedule a call to the user-defined R functions in app to handle the request. This scheduling is done with later(). When the R call stack is empty – in other words, when an interactive R session is sitting idle at the command prompt – R will automatically run the scheduled calls. However, if the call stack is not empty – if R is evaluating other R code – then the callbacks will not execute until either the call stack is empty, or the run_now() function is called. This function tells R to execute any callbacks that have been scheduled by later(). The service() function is essentially a wrapper for 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")