分离并附加 RServe 连接:无法连接
Detach and attach RServe connection: Cannot connect
我正在尝试从 Java 分离然后附加一个 RServe 会话。连接到 RServe 工作完美,但附加会导致异常。
package com.company.korana.r_interface;
import org.rosuda.REngine.Rserve.RConnection;
import com.company.korana.config.Config$;;
public class RToast {
public static void main(String[] args) throws Exception {
RConnection rConnection = new RConnection(Config$.MODULE$.rserveHost(), Config$.MODULE$.rservePort());
rConnection.assign("testVariable", "hello from java");
rConnection.eval("print('Hi R console from java')"); // <--- this is visible in the R console
org.rosuda.REngine.Rserve.RSession sessionHandle = rConnection.detach();
rConnection = sessionHandle.attach(); // <---- this throws
System.out.println(rConnection.eval("testVariable").asString());
}
}
Exception in thread "main" org.rosuda.REngine.Rserve.RserveException:
Cannot connect: Connection refused: connect at
org.rosuda.REngine.Rserve.RConnection.(RConnection.java:90) at
org.rosuda.REngine.Rserve.RConnection.(RConnection.java:66) at
org.rosuda.REngine.Rserve.RSession.attach(RSession.java:36) at
com.company.korana.r_interface.RToast.main(RToast.java:16) Caused by:
java.net.ConnectException: Connection refused: connect at
java.net.DualStackPlainSocketImpl.connect0(Native Method) at
java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at
java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at
java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at
java.net.AbstractPlainSocketImpl.connect(Unknown Source) at
java.net.PlainSocketImpl.connect(Unknown Source) at
java.net.SocksSocketImpl.connect(Unknown Source) at
java.net.Socket.connect(Unknown Source) at
java.net.Socket.connect(Unknown Source) at
java.net.Socket.(Unknown Source) at
java.net.Socket.(Unknown Source) at
org.rosuda.REngine.Rserve.RConnection.(RConnection.java:85) ...
3 more
Rserve 在具有默认端口的本地主机上 运行。
编辑:
我正在使用以下 Maven 工件:
<dependency>
<groupId>org.rosuda.REngine</groupId>
<artifactId>Rserve</artifactId>
<version>1.8.1</version>
</dependency>
检查来源后,发现 Rserve 会话在分离时侦听随机分配的端口。
Rserv.c,第 1781 行
while ((port = (((int) random()) & 0x7fff)+32768)>65000) {};
因此客户端和 Rserve 之间需要可达的端口介于 32768 和 65000 之间。在我的例子中,这不起作用,因为我使用的是 docker。
编辑:我构建了一个解决方案,将 Rserve 与 docker 一起使用,而无需打开大量端口(这与 docker 不能很好地配合)。下面的截图替换了我的 install.packages("Rserve"):
RUN wget https://www.rforge.net/src/contrib/Rserve_1.8-5.tar.gz
RUN tar -xf Rserve_1.8-5.tar.gz
RUN rm Rserve_1.8-5.tar.gz
RUN sed -i '1763s/.*/\t\tint port = 53000;/' /Rserve/src/Rserv.c
RUN sed -i '1781s/.*//' /Rserve/src/Rserv.c
RUN sed -i '1793s/.*/\t\tif (port>53100) {/' /Rserve/src/Rserv.c
RUN tar -czvf Rserve_1.8-5.tar.gz /Rserve
RUN R CMD INSTALL Rserve_1.8-5.tar.gz
这会修改 Rserve 源,以便在 [53000, 53100] 范围内使用端口[这对我来说已经足够了。
我正在尝试从 Java 分离然后附加一个 RServe 会话。连接到 RServe 工作完美,但附加会导致异常。
package com.company.korana.r_interface;
import org.rosuda.REngine.Rserve.RConnection;
import com.company.korana.config.Config$;;
public class RToast {
public static void main(String[] args) throws Exception {
RConnection rConnection = new RConnection(Config$.MODULE$.rserveHost(), Config$.MODULE$.rservePort());
rConnection.assign("testVariable", "hello from java");
rConnection.eval("print('Hi R console from java')"); // <--- this is visible in the R console
org.rosuda.REngine.Rserve.RSession sessionHandle = rConnection.detach();
rConnection = sessionHandle.attach(); // <---- this throws
System.out.println(rConnection.eval("testVariable").asString());
}
}
Exception in thread "main" org.rosuda.REngine.Rserve.RserveException: Cannot connect: Connection refused: connect at org.rosuda.REngine.Rserve.RConnection.(RConnection.java:90) at org.rosuda.REngine.Rserve.RConnection.(RConnection.java:66) at org.rosuda.REngine.Rserve.RSession.attach(RSession.java:36) at com.company.korana.r_interface.RToast.main(RToast.java:16) Caused by: java.net.ConnectException: Connection refused: connect at java.net.DualStackPlainSocketImpl.connect0(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.(Unknown Source) at java.net.Socket.(Unknown Source) at org.rosuda.REngine.Rserve.RConnection.(RConnection.java:85) ... 3 more
Rserve 在具有默认端口的本地主机上 运行。
编辑: 我正在使用以下 Maven 工件:
<dependency>
<groupId>org.rosuda.REngine</groupId>
<artifactId>Rserve</artifactId>
<version>1.8.1</version>
</dependency>
检查来源后,发现 Rserve 会话在分离时侦听随机分配的端口。
Rserv.c,第 1781 行
while ((port = (((int) random()) & 0x7fff)+32768)>65000) {};
因此客户端和 Rserve 之间需要可达的端口介于 32768 和 65000 之间。在我的例子中,这不起作用,因为我使用的是 docker。
编辑:我构建了一个解决方案,将 Rserve 与 docker 一起使用,而无需打开大量端口(这与 docker 不能很好地配合)。下面的截图替换了我的 install.packages("Rserve"):
RUN wget https://www.rforge.net/src/contrib/Rserve_1.8-5.tar.gz
RUN tar -xf Rserve_1.8-5.tar.gz
RUN rm Rserve_1.8-5.tar.gz
RUN sed -i '1763s/.*/\t\tint port = 53000;/' /Rserve/src/Rserv.c
RUN sed -i '1781s/.*//' /Rserve/src/Rserv.c
RUN sed -i '1793s/.*/\t\tif (port>53100) {/' /Rserve/src/Rserv.c
RUN tar -czvf Rserve_1.8-5.tar.gz /Rserve
RUN R CMD INSTALL Rserve_1.8-5.tar.gz
这会修改 Rserve 源,以便在 [53000, 53100] 范围内使用端口[这对我来说已经足够了。