断开并连接RServe连接:无法连接

时间:2017-01-26 15:10:41

标签: java r rserve

我试图分离然后从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());
    }
}
  

线程“main”中的异常org.rosuda.REngine.Rserve.RserveException:   无法连接:连接被拒绝:连接在   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)引起:   java.net.ConnectException:拒绝连接:connect at   java.net.DualStackPlainSocketImpl.connect0(Native Method)at   java.net.DualStackPlainSocketImpl.socketConnect(未知来源)at   java.net.AbstractPlainSocketImpl.doConnect(未知来源)at   java.net.AbstractPlainSocketImpl.connectToAddress(未知来源)at   java.net.AbstractPlainSocketImpl.connect(未知来源)at   java.net.PlainSocketImpl.connect(未知来源)at   java.net.SocksSocketImpl.connect(未知来源)at   java.net.Socket.connect(未知来源)at   java.net.Socket.connect(未知来源)at   java.net.Socket。(未知来源)at   java.net.Socket。(未知来源)at   org.rosuda.REngine.Rserve.RConnection。(RConnection.java:85)...   还有3个

Rserve使用默认端口在localhost上运行。

编辑: 我正在使用以下maven工件:

<dependency>
    <groupId>org.rosuda.REngine</groupId>
    <artifactId>Rserve</artifactId>
    <version>1.8.1</version>
</dependency>

1 个答案:

答案 0 :(得分:0)

在检查了源之后,事实证明Rserve会话在分离时会监听随机分配的端口。

Rserv.c,第1781行

while ((port = (((int) random()) & 0x7fff)+32768)>65000) {};

因此,客户端和Rserve之间需要可以访问的端口在32768和65000之间。在我的情况下,这不起作用,因为我使用的是docker。

编辑:我构建了一个解决方案,将Rserve与docker一起使用,而无需打开大量端口(与docker不兼容)。下面的snipper替换了我的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 [在我的情况下就足够了]范围内获取端口。