将表达式传递给evalServer

时间:2013-11-07 16:40:10

标签: r svsocket

使用包svSocket我试图在服务器中执行通用表达式

expr <- "demo<-new.env()"
evalServer(con, expr, expr)
> evalServer(con, parse(text=expr))
Error in source(objcon, local = TRUE, echo = FALSE, verbose = FALSE) : 
  objcon:1:65: unexpected '<'
1: ..Last.value <-structure(expression(demo<-new.env()), srcfile = <

我该如何避免? PS:我需要以编程方式在服务器中创建对象。例如demo将来自用户输入并粘贴()d到上面的字符串中。

可重复示例###打开两个rsession

# run in the 1st rsession
require(svSocket)
startSocketServer()

# run in the 2nd rsession
con <- socketConnection(host = "localhost", port = 8888, blocking = FALSE)
expr <- "demo<-new.env()"
evalServer(con, expr, expr)

1 个答案:

答案 0 :(得分:1)

以下是您想要做的解决方法。

首先,在终端窗口中使用套接字服务器启动R:

$ R
> require(svSocket)
> startSocketServer()
> 

然后,在另一个R进程中,加载svSocket,连接到套接字服务器并使用evalServer()

$ R
> require(svSocket)
> options(prompt = "RClient> ")
RClient> con <- socketConnection(host = "localhost", port = 8888, blocking = FALSE)

现在,evalServer()通过序列化反序列化R对象以便通过套接字发送它们。并非所有R对象都是可序列化的......并且环境是导致问题的对象之一。

可以执行您想要的操作,但必须注意环境对象永远不会从客户端传递到服务器或返回。一种方法是将指令作为文本字符串发送(确保返回环境):

RClient> evalServer(con, expr, "demo <- new.env(); NULL")

然后,您必须指示服务器解析并评估他身边的代码。来自客户:

RClient> evalServer(con, eval(parse(text = expr)))

您可以检查是否在服务器中创建了演示对象,并且在客户端内是正确的类(此处对象是可序列化的,因此没有问题):

RClient> evalServer(con, ls())
[1] "demo" "expr"
RClient> evalServer(con, class(demo))
[1] "environment"
RClient> 

当然,当您从客户端操作“demo”时,您也必须小心。不要忘记最后:

RClient> close(con)