的核心AnalysisPageServer的服务器端系统是一个从处理程序函数映射到web服务。您定义的集合构建一个函数来表示AnalysisPageRegistry
,然后在车部署应用程序(运行在您的本地R服务器)或Apache使用Rapache系统。
内置对象处理程序函数调用AnalysisPage
年代。AnalysisPage
可以是一个服务,该服务可能会返回例如任意JSON字符串,也可以是一个完全交互式页面,例如使情节和返回一个数据帧。本文解释了简单的服务型AnalysisPage
。这也解释了如何部署应用程序与车。描述交互式页面和服务器另一个页面。
车版本> = 1.1和叉在这个描述所需的例子。我要检查是否可用。
# #车> = 1.1或叉不可用,因此,尽管你仍然可以使用静态报表AnalysisPageServer # #的特性,动态服务器和部署FastRWeb和RApache你# #将无法部署使用车/ Rhttpd,或者建立适当的这一幕。你会看到# #消息“车> = 1.1 +叉不可用”在所有的点在这个描述# #车+叉会被要求:启动服务器,查询服务器和停止# #服务器。如果你想要你可以安装/更新失踪的依赖关系是这样的:# # # # install.packages(“叉”)# # install.packages (devtools)图书馆(devtools) # # # # install_github(“车”、“jeffreyhorner”)
服务型AnalysisPage
年代建造的build.service ()
构造函数。所有你要做的就是通过一个处理函数,给它一个名字:
库(AnalysisPageServer)你好< - build.service(函数()“你好,世界!”name = "你好")类(你好)
# # [1]“AnalysisPage”
注意:尽管我们将演示,这是一个服务,而不是一个成熟的web页面我们仍然称之为一个
AnalysisPage
。以来,从服务器的角度来看,没有多少区别网络服务和web页面中,在这个文档时我通常只是说“页面”说“页面或服务”会更准确。
接下来,我们建立一个AnalysisPageRegistry
。本例中只有一个AnalysisPage
,不是很有趣,但是我们仍然需要这个对象:
reg < - new.registry(你好)类(注册)
# # [1]“AnalysisPageRegistry”
一个AnalysisPageRegistry
不是比一个查找AnalysisPage
年代。你可以得到所有注册页面的名称:
页面(reg,包括。服务= TRUE)
# #[1]“你好”
的include.services
开关必须打开,因为默认只返回互动页面,和你好
没有互动。
您可以检索一个特定的页面:
相同的(。页面(reg,“你好”),你好)
# # [1]
一旦注册对象构建它可以部署。在本文档页面,我们将部署我们所有的应用程序通过使用本地R服务器车。这是有用的用于开发和非正式但生产规模RApache或FastRWeb部署是必需的。车+ Rhttpd不处理并发的组合,通常倾向于事故很多。同时,一些版本的车只会监听当地lookback设备,这将避免与任何人共享您的服务器。
注意:你所选择的部署是完全独立于如何构建
AnalysisPageRegistry
,这是这个文档页面的主要焦点。
现在我们将启动服务器:
端口< - 3198 # #或其他端口服务器< - startRookAnalysisPageServer (reg,端口=端口)服务器
“车> = 1.1 +叉不可用”
请注意,这个函数startRookAnalysisPageServer
启动服务器在一个新的进程。这似乎比典型的车稍微稳定部署在同一进程中,你继续计算可能会妨碍传入的请求。特别是,如果你试图从相同的R过程调用服务器挂起。可以传递给这个函数返回的对象kill.process ()
关闭服务器:
kill.process(服务器)
“车> = 1.1 +叉不可用”
开始一个新的进程的缺点是,你可能会忘记你辞职r .这不仅浪费系统资源,但它实际上拥有港口,这意味着你无法开始另一个端口的服务器。为了防止这种情况,你应该开始你的服务器的习惯两行代码:
服务器< - startRookAnalysisPageServer (reg,端口=端口)on.exit(试试(kill.process(服务器)))
第二行寄存器表达式时评定R退出,这确保了孩子不生存。自触发的on.exit
处理程序是有点棘手knitr
环境我们将显式的调用kill.process(服务器)
在这个文档。
如果你是一个车书呆子和想做的更漂亮的东西,像把这车应用程序和其他应用程序,然后你可以得到车的应用对象是这样的:
应用< - new.rook.analysis.page.app(注册)
与这个对象你也有部署服务器的可能性在正常车方式,避免使用叉
包中。
车。服务器< -车:Rhttpd美元新()车。服务器添加美元(app, name = "罪行")车。服务器开始美元(端口=端口)# # Ping服务器从另一个R过程或从web浏览器…# #然后停止服务器rook.server美元停止()
“车> = 1.1 +叉不可用”
我们提供的startRookAnalysisPageServer ()
函数来启动服务器,而不是直接连接车:Rhttpd ()
。这个函数接受一个AnalysisPageRegistry
对象,因此你不需要建立你的车对象,并使用叉
包在子进程启动服务器。这让我们从父进程调用服务器,否则块。它也很容易从灾难中恢复,只要杀死子进程,而无需重新启动父R过程。
让我们打开服务器,看看它是如何工作的。
服务器< - startRookAnalysisPageServer (reg,端口=端口)
然后打开你的浏览器:
解剖的URL: 127.0.0.1是车使用的环回设备————意味着你的本地主机。这个演示页面的端口是一个任意的选择(抱歉如果端口从这个屏幕截图不匹配这个文档)的端口。如果你不指定一个端口然后车/ R将随机选择一个给你,每一次你试试你的服务器将不得不修改端口。不能修改/定制”前缀,即车+ Rhttpd是如何工作的。“罪行”是我在车命名服务器。“R /分析”中一个前缀
AnalysisPageServer
系统所有页面的位置。最后,json编码的页面的名称,形成完整的请求。
一旦服务器运行我们可以查询它在理论上从任何远程语言,甚至可能。在本文档中,我们将演示服务器正在通过构造URL(使用service.link
函数),然后调用readline ()
。
app.base。< url - paste0 (“http://127.0.0.1”,港口,“/定制/敲”)< -服务url。链接(页面= "你好",app.base。url = app.base.url)猫(readline (url,警告= FALSE),“\ n”)
# #“车> = 1.1 +叉不可用”
(警告= FALSE
被添加到readline
调用incompete最后一行的警告消息)。
这是“Hello, World !”。
敏锐的观察者注意到问候字符串引用的反应,即使它是显示猫
而不是正常的R输出。这样做的原因是,所有json编码的自动反应。在这之后,以及如何关掉它。
kill.process(服务器)
“车> = 1.1 +叉不可用”
我们把两页在同一个应用程序中。我们将重用你好
页面也有计算一个参数的正弦函数:
正弦< - build.service(函数(θ)罪(θ),name =“正弦”)注册< -新。注册表(sin,你好)服务器< - startRookAnalysisPageServer (reg,端口=端口)
正如上面提到的,所有的返回值是默认情况下json编码的。我们可以使用fromJSON
函数把它们回到R对象。出于演示的目的在这个文档我们会总结的步骤构建URL,调用服务器,响应和解码成一个函数:
秀。分析< -函数(params =()列表,页面显示。url = FALSE) {< url -服务。链接(页面、params app.base.url)如果(show.url)猫(url,“\ n”)响应<——readline (url,警告= FALSE) rjson:: fromJSON(响应)}。分析(“hello”,显示。url = TRUE)
# # http://127.0.0.1:3198 /定制/敲/ R /分析? = % 22你好% 22页
# #[1]“车> = 1.1 +叉不可用”
秀。分析(“正弦”,列表(θ= 3.141592653),表演。url = TRUE)
# # http://127.0.0.1:3198 /定制/敲/ R /分析? page = % 22正弦% 22 e141592653θ= 3% 2
# #[1]“车> = 1.1 +叉不可用”
kill.process(服务器)
“车> = 1.1 +叉不可用”
无论你的函数返回将JSON编码toJSON
。
残雪。返回< - build.service(函数(){列表(A = 1:5, B =“我能”,C =列表(x = 1, y = C(真的,假,真的)))},name = "复杂")reg < - new.registry (cx.return)服务器< - startRookAnalysisPageServer (reg,端口=端口)show.analysis(“复杂”)
# #[1]“车> = 1.1 +叉不可用”
kill.process(服务器)
“车> = 1.1 +叉不可用”
参数的URL解码然后JSON解码然后传递给函数。这个处理程序需要一个复杂的结构和一个整数作为参数。与数组元素的结构应该是一个散列键“a”。元素的数组索引返回的整数。
残雪。参数< -构建。服务(功能(结构,n){在Javascript: # # # #结构[A] [n - 1] struct美元[n]}, name = " cxpar ") reg < - new.registry (cx.param)服务器< - startRookAnalysisPageServer (reg,端口=端口)。分析(“cxpar”,列表(struct =列表(A = c (3、1、4、1、5、9、2、6、5、3)), n = 6),表演。url = TRUE)
# # http://127.0.0.1:3198 /定制/敲/ R /分析? page = % 22 cxpar % 22 struct = % 7 b % 22 % % 5 3 22% b3 % 2 c1 % 2 c4 % 2 c1 % 2 c5 % 2 c9 % 2 c2 % 2 c6 % 2 c5 % 2 c3 % 5 d % 7 d&n = 6
# #[1]“车> = 1.1 +叉不可用”
kill.process(服务器)
“车> = 1.1 +叉不可用”
有时自动JSON编码的响应是一个麻烦。或者,您可能希望设置响应的MIME类型。如果您显式地返回一个AnalysisPageResponse
对象可以有更好的控制。这是完成了new.response
构造函数。
在这个例子中,我们返回一个完整的HTML页面。
诗。文件< -执行(“/ in-a-station-of-the-metro例子。html”,包= " AnalysisPageServer”)的诗。html < - readline(诗。文件,警告= FALSE)诗< - build.service(函数(){new.response (paste0(诗。html、“\ n”)的内容。type = " text / html ")}, name = "诗")reg < - new.registry(诗)服务器< - startRookAnalysisPageServer (reg,端口=端口)< url -服务。链接(app.base“诗”。url = app.base.url) readline (url,警告= FALSE)
“车> = 1.1 +叉不可用”
或在浏览器中打开它:
kill.process(服务器)
“车> = 1.1 +叉不可用”
的new.response
构造函数让我们返回其他事情。例如,我们甚至可以把一块响应。让我们编码Maunga Whau火山的情节,我们做的静态内容示例页面。我们将使用RreadBin
读成原始矢量因为它是二进制数据。
单参数的函数将一个数组用于颜色渐变颜色。
火山< -构建。服务(功能(颜色= c(“红”、“白”、“紫色”)){plotfile < - tempfile (fileext = . png) png (plotfile、宽= 600,高= 400)标准(mar = c (1、1、4、1) < - colorRampPalette上校(颜色)(50)图像(数据集::火山,xaxt =“n”, yaxt =“n”,主要=“Maunga Whau火山”,=上校,上校cex。情节主要= 2)dev.off ()。数据< - readBin (plotfile、“原始”,n = file.info (plotfile)[, "大小"])。响应(身体=阴谋。数据、内容。类型=“图像/ png”)}, name =“火山”)注册< - new.registry(火山)服务器< - startRookAnalysisPageServer (reg,端口=端口)
一个四色的火山:
如果颜色
参数是省略了然后从函数定义将使用默认值(在本例中红、白、紫色):
kill.process(服务器)