2013-04-21 28 views
10

Tôi đang viết chương trình Java GUI để quản lý tuyến tĩnh bằng SSH. Mã của tôi là như sau:JSch: Làm thế nào để giữ cho phiên còn sống và lên

import com.jcraft.jsch.*; 
import java.io.*; 

public class Konsep { 
    String status; 
    static String username; 
    static String hostname; 
    String inputcommand; 
    String output; 
    static Session session; 

    JSch jsch = new JSch(); 

    public String status(String stringstatus) { 
     stringstatus = status; 
     return stringstatus; 
    } 

    public String InputCommand(String inputcommandstatus) { 
     inputcommandstatus = inputcommand; 
     return inputcommandstatus; 
    } 

    public void connect(String usernamelokal, String hostnamelokal, 
      String password, int port) { 
     //  JSch jsch=new JSch(); 
     try { 
      Session sessionlokal = jsch.getSession(usernamelokal, 
        hostnamelokal, port); 
      sessionlokal.setPassword(password); 
      UserInfo ui = new UserInfoku.Infoku(); 
      sessionlokal.setUserInfo(ui); 
      sessionlokal.setTimeout(0); 
      sessionlokal.connect(); 
      status = "tersambung \n"; 
      username = usernamelokal; 
      hostname = hostnamelokal; 
      session = sessionlokal; 
      System.out.println(username + " " + hostname); 
     } catch (Exception e) { 
      System.out.println(e); 
      status = "Exception = \n " + e + "\n"; 

     } 
    } 

    public void disconnect() { 
     //  JSch jsch=new JSch(); 
     try { 
      Session sessionlokal = jsch.getSession(username, hostname); 
      //   System.out.println(username +" "+ hostname); 
      sessionlokal.disconnect(); 
      status = "wes pedhoott \n"; 
     } catch (Exception e) { 
      System.out.println(e); 
      status = "Exception = \n " + e + "\n"; 
     } 

    } 

    public void addRoute() { 
     //  JSch jsch=new JSch(); 
     System.out.println(username + " " + hostname); 
     try { 
      Session sessionlokal = session; // =jsch.getSession(username, hostname); 
      Channel channel = sessionlokal.openChannel("exec"); 
      ((ChannelExec) channel).setCommand(inputcommand); 
      channel.setInputStream(null); 
      channel.connect(); 
      ((ChannelExec) channel).setErrStream(System.err); 
      InputStream in = channel.getInputStream(); 
      channel.connect(); 

      byte[] tmp = new byte[1024]; 
      while (true) { 
       while (in.available() > 0) { 
        int i = in.read(tmp, 0, 1024); 
        if (i < 0) 
         break; 
        System.out.print(new String(tmp, 0, i)); 
       } 
       if (channel.isClosed()) { 
        System.out.println("exit-status: " 
          + channel.getExitStatus()); 
        break; 
       } 
       try { 
        Thread.sleep(1000); 
       } catch (Exception ee) { 
       } 
      } 

      channel.disconnect(); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 
}  

Vấn đề là khi tôi gọi phương thức kết nối và sau đó gọi addroute, chương trình trả

root 192.168.50.2 
root 192.168.50.2 
com.jcraft.jsch.JSchException: session is down 

Tôi đã cố gắng để có được tình trạng phiên với một trong hai

Session sessionlokal=session; //returns com.jcraft.jsch.JSchException: ChannelExec 

hoặc

Session sessionlokal=jsch.getSession(username, hostname); //returns session is down 

Tôi cũng đã cố gắng sử dụng keepalive, nhưng nó không hoạt động. Mục đích của tôi là tạo phiên để lưu trữ (đăng nhập), trong khi rời phiên, thực hiện lệnh hoặc lệnh và có thể thực hiện các lệnh khác sau đó, sau đó đóng phiên khi không cần (đăng xuất). Tôi đã tìm kiếm trên diễn đàn này và tôi thấy điều này question nhưng mã được tạo ra một phương pháp để xác định một lệnh để thực hiện đầu tiên, và sau đó tạo phiên, gọi phương thức của lệnh và đóng phiên.

Bất kỳ ý tưởng nào về cách thực hiện như tôi đã đề cập ở trên?

Trả lời

10

Sau khi thử Session.sendKeepAliveMsg() nhưng không thành công, tôi đã đến giải pháp sau đây mà có vẻ là khá ổn định:

private Session getSession() throws Exception { 
    try { 
     if (!session.isConnected()) { 
      logger.info("Session nicht konnektiert. Versuche (erneut) zu konnektieren."); 
      session.connect(); 
     } 
    } catch (Throwable t) { 
     logger.info("Session kaputt. Baue neue."); 
     session = jsch.getSession(user, host, port); 
     session.setConfig(config); 
     session.connect(); 
    } 
    return session; 
} 

Cập nhật: Vài ngày sau đó thất bại.

Tôi đã cố gắng kiểm tra bằng cách giết phiên mở trên máy chủ. Tất cả các phiên bản trước mà tôi đã thử nghiệm theo cách này cho thấy hành vi giống hệt nhau, bất kể vấn đề nào xuất hiện sau khi chờ đợi một vài ngày hoặc giết chết quá trình máy chủ, vì vậy tôi nghĩ thử nghiệm này - và kết quả của nó cho giải pháp trên - có ý nghĩa. Thật không may nó không phải là.

Tôi sẽ thử một số cách khác để khắc phục sự cố và cập nhật cho bạn.

Cập nhật 2: giải pháp cuối cùng, guarateed unelegant và làm việc:

private Session getSession() throws Exception { 
    try { 
     ChannelExec testChannel = (ChannelExec) session.openChannel("exec"); 
     testChannel.setCommand("true"); 
     testChannel.connect(); 
     if(logger.isDebugEnabled()) { 
      logger.debug("Session erfolgreich getestet, verwende sie erneut"); 
     } 
     testChannel.exit(); 
    } catch (Throwable t) { 
     logger.info("Session kaputt. Baue neue."); 
     session = jsch.getSession(user, host, port); 
     session.setConfig(config); 
     session.connect(); 
    } 
    return session; 
} 

Phiên bản này chạy vài tuần trong một môi trường sản xuất. Mỗi ngày một lần, tôi đã ghi thông tin thông tin.

Chi phí mở kênh và thực hiện một số lệnh không có gì gây phiền toái, nhưng tôi không tìm thấy cách nào khác để chắc chắn chắc chắn về trạng thái của phiên.

+0

giải pháp tốt, chỉ một gợi ý: tôi sẽ thêm 'testChannel.exit();' sau khi kiểm tra thành công, nếu không bạn kết thúc bằng một quy trình daemon sftp-server ở phía máy chủ cho mỗi séc – GWu

+0

Cảm ơn.Đã thêm 'testChannel.exit()'. – blafasel

+0

Tôi gặp sự cố bế tắc khi mở nhiều kênh. Làm cho getSession() 'synchronised' giải quyết được điều này, nhưng đó là một chút thành công. Bạn có biết phần nào cần được đồng bộ không? Có lẽ kênh thử nghiệm kết nối = ngắt kết nối? –

Các vấn đề liên quan