Java RMI 超时
Java RMI timeout
我使用 Java RMI 编写了一个 client/server 应用程序。当我在本地 运行 这个应用程序时(客户端和服务器中的 IP 字符串都设置为本地 IP),脚本工作正常。
客户代码:
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());
}
}
}
现在传输到服务器的 User 和 UserHandler 的接口和 classes:
接口用户:
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;
}
Class 用户处理程序:
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;
}
}
Class 用户:
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 时,它启动正常。
因此,在 class UserHandler 中有以下行:
System.out.println(user.getUserName() + " logged in");
只打印String,没有任何用户Object,在客户端执行方法后,打印行出现提示
当只打印带有用户的 println(但没有方法调用 getUserNAme())时,需要 10-15 秒才能打印。
使用上面的语句,没有任何反应,我得到一个超时异常。
在测试环境中,我打开了TCP的所有端口以确保消息到达。
有人可以帮帮我吗?谢谢!
您正在使用回调,这意味着您正在打开到客户端的连接,这意味着客户端的防火墙必须打开。
我强烈建议您取消回调并使 User
成为可序列化对象。
我使用 Java RMI 编写了一个 client/server 应用程序。当我在本地 运行 这个应用程序时(客户端和服务器中的 IP 字符串都设置为本地 IP),脚本工作正常。
客户代码:
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());
}
}
}
现在传输到服务器的 User 和 UserHandler 的接口和 classes:
接口用户:
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;
}
Class 用户处理程序:
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;
}
}
Class 用户:
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 时,它启动正常。
因此,在 class UserHandler 中有以下行:
System.out.println(user.getUserName() + " logged in");
只打印String,没有任何用户Object,在客户端执行方法后,打印行出现提示
当只打印带有用户的 println(但没有方法调用 getUserNAme())时,需要 10-15 秒才能打印。
使用上面的语句,没有任何反应,我得到一个超时异常。
在测试环境中,我打开了TCP的所有端口以确保消息到达。
有人可以帮帮我吗?谢谢!
您正在使用回调,这意味着您正在打开到客户端的连接,这意味着客户端的防火墙必须打开。
我强烈建议您取消回调并使 User
成为可序列化对象。