web-dev-qa-db-fra.com

Limite de délai de session JSch

J'utilise JSch 0.1.50 pour configurer une connexion au serveur distant pour mon plug-in CI Jenkins. Supposons que j'essaie d'utiliser ici session.connect(60000); pour le délai d'attente de 60 secondes:

Session session = null;
try {
    JSch jsch = new JSch();
    if (rsaIdentity != null && !rsaIdentity.equals("")) {
        jsch.addIdentity(rsaIdentity.trim());
    }
    session = jsch.getSession(serverLogin, serverHost, Integer.parseInt(serverPort));
    session.setPassword(getDescriptor().getOpenPassword(encryptedPasswordString));
    session.setConfig("StrictHostKeyChecking", "no"); // not use RSA key

    int timeOut = Integer.parseInt(getDescriptor().getConnectionTimeOut());

    session.connect(60000);

} catch (SocketTimeoutException e) {
    logger.error(e.getMessage());
    return false;
} catch (JSchException e) {
    logger.error(e.getMessage());
    return false;
}

Mais en fait, lors de l'exécution de ce code lors de la connexion à un serveur assez lent, je suis confronté au délai d'attente Exception toutes les 20 secondes environ:

2016-01-25 13:15:55.982 [INFO] Connecting to server: devsrv26:22 as [user] ...
2016-01-25 13:16:16.991 [ERROR] Java.net.ConnectException: Connection timed out: connect
2016-01-25 13:16:16.992 com.jcraft.jsch.JSchException: Java.net.ConnectException: Connection timed out: connect
2016-01-25 13:16:16.992     at com.jcraft.jsch.Util.createSocket(Util.Java:389)
2016-01-25 13:16:16.993     at com.jcraft.jsch.Session.connect(Session.Java:215)
2016-01-25 13:16:16.993     at com.mycomp.jenkins.MyPlugin.perform(MyPlugin.Java:225)

76991-55982 = 21008 ms

Est-ce que quelqu'un sait quelle est la raison de ce délai d'attente de 20 secondes?

7
Khmelevskikh Alex

Si vous vérifiez comment le Util.createSocket est implémenté, vous verrez que la timeout définit uniquement une limite supérieure de la connexion, et non une limite inférieure, car timeout n'est étrangement pas transmis à une Socket sous-jacente.

Ces 20 secondes sont probablement une limite par défaut au niveau du système d'exploitation.

Pour le remplacer, essayez d'implémenter le SocketFactory et attachez-le à la session à l'aide du Session.setSocketFactory .

En usine, utilisez la Socket.connect(SocketAddress endpoint, int timeout) .

Quelque chose comme:

public class SocketFactoryWithTimeout implements SocketFactory {
  public Socket createSocket(String Host, int port) throws IOException,
                                                           UnknownHostException
  {
    socket=new Socket();
    int timeout = 60000;
    socket.connect(new InetSocketAddress(Host, port), timeout);
    return socket;
  }

  public InputStream getInputStream(Socket socket) throws IOException
  {
    return socket.getInputStream();
  }

  public OutputStream getOutputStream(Socket socket) throws IOException
  {
    return socket.getOutputStream();
  }
}
2
Martin Prikryl