0

使用该包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,将来自用户输入并将 paste()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)
4

1 回答 1

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> 

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

RClient> close(con)
于 2013-11-08T13:06:52.200 回答