2016-02-15 65 views
0

我使用Java RMI编写了客户端/服务器应用程序。当我在本地运行这个应用程序时(在客户端和服务器中的IP字符串都设置为本地IP),脚本工作正常。Java RMI超时

客户端代码:

public class ClientMain { 
public static void main(String[] args) { 


    String ip = "123.123.123.123"; // (my server's IP) 


    IUserHandler userHandler; 
    try { 
     userHandler = (IUserHandler) Naming.lookup("//"+ip+"/Server"); 
     System.out.println(userHandler.attachUser(new User("John"))); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
} 

服务器代码:

public class MainServer { 
public static void main(String[] args) { 

    String ip = "123.123.123.123"; // (my server's IP) 

    System.out.println("Start Server at " + ip); 
    try { 
     System.setProperty("java.rmi.server.hostname",ip); 
     LocateRegistry.createRegistry(Registry.REGISTRY_PORT); 
     Naming.rebind("Server",new UserHandler()); 

     System.out.println("Server is running"); 
    } catch (Exception ex) { 
     System.out.println(ex.getMessage()); 
    } 
} 
} 

现在的界面和用户和UserHandler,其被输送到服务器的类:

接口IUser:

public interface IUser extends Remote { 
    public String getUserName() throws RemoteException; 
    public void setUserName(String name) throws RemoteException; 
} 

接口IUserHandler:

public interface IUserHandler extends Remote { 
    public int attachUser(IUser user) throws RemoteException; 
    public int detachUser(String name) throws RemoteException; 
} 

类UserHandler:

public class UserHandler extends UnicastRemoteObject implements IUserHandler { 
public UserHandler() throws RemoteException {} 

@Override 
public int attachUser(IUser user) throws RemoteException { 
    System.out.println(user.getUserName() + " logged in"); 
    return 1; 
} 

@Override 
public int detachUser(String name) throws RemoteException{ 
    return 1; 
} 
} 

类用户:

public class User extends UnicastRemoteObject implements IUser { 
private String name; 

public User(String name) throws RemoteException { 
    super(); 
    this.name = name; 
} 

@Override 
public String getUserName() { 
    return name; 
} 

@Override 
public void setUserName(String name) { 
    this.name = name; 
} 

} 

服务器应用程序应在Windows Server 2012计算机上运行。当我在服务器上运行生成的jar时,它启动正常。

所以,在类UserHandler有下面的行:

System.out.println(user.getUserName() + " logged in"); 

当只打印而无需任何用户Object的String,印刷线出现在客户端执行该方法后提示。
当仅打印带用户(但没有方法调用getUserNAme())的println时,需要打印10-15秒。 用上面的语句,没有任何反应,我得到一个超时异常。

在测试环境中,我打开TCP的所有端口以确保消息到达。

有人可以帮我吗?谢谢!

回答

1

您正在使用回调,这意味着您正在打开与客户端的连接,这意味着客户端的防火墙必须处于打开状态。

我强烈建议你摆脱回调并使User成为一个Serializable对象。

+0

感谢您的回复。我已经尝试了两种方法,扩展了User Serializable和IUser接口。我之前删除了'extends UnicastRemoteObject'。现在我收到以下错误: java.rmi.ServerException:在服务器线程中发生RemoteException;嵌套的异常是: java.rmi.UnmarshalException:错误解组参数;嵌套的异常是: java.lang.ClassNotFoundException:用户 在sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:354) 我没有碰其他类。我究竟做错了什么? – Exx3

+0

该消息已足够清楚。名为的类未部署。部署它。 – EJP