2011-09-10 72 views
2

大家好,传递使用RMI的对象引用

我一直在砸我的脑袋,努力解决这个问题。我真的很感激,如果有人可以请看看我的问题,并帮助我。

我有一个使用Java RMI建立连接多个客户端(注册()),并接收来自服务器的客户端连接的列表(get()方法)。我的目标是让客户使用RMI相互交谈,而不必注册自己,只有服务器到目前为止正在注册。

我试图通过客户对象服务器的参考。

我收到以下错误:

java.rmi.MarshalException: error marshalling arguments; nested exception is: 
    java.io.NotSerializableException: Client 

我不想使用序列化(我认为),因为我不希望传递的对象本身,而是一个参考。 Client1应该能够通过调用client2.messsage(String username,String message)向Client2发送消息;

我相信我应该在这一点告诉你如何我已经实现了我的代码:

public interface RMIClientIntf extends Remote { 
    public void message(String name, String message) throws RemoteException; 
    public String getName() throws RemoteException; 
} 

前面的代码是什么,所有的客户应该实施。如果从另一个客户端调用message()函数,那意味着其他类正在发送消息。

我的客户类本身:

public class Client implements RMIClientIntf { 
    public Client() throws RemoteException { super(); } 
    public String getName() throws RemoteException { } 
} 

现在,创建客户端的一个实例调用下面的主类,远程对象发送到服务器:

final Client client = new Client(); 
server.register((RMIClientIntf) client, name); 

在服务器侧,注册方法定义为:

public interface RMIServerIntf extends Remote { 
    public String register(RMIClientIntf cl, String userName) throws RemoteException; 
    public RMIClientIntf[] get() throws RemoteException; 
} 


public class Server extends UnicastRemoteObject implements RMIServerIntf { 
    public String register(RMIClientIntf cl, String userName) throws RemoteException { 
     ClientStruct newClient = new ClientStruct(cl, userName); 
     /* Store the ClientStruct */ 
     return new String("SUCCESS"); 
    } 
} 

注册后,每个客户端将req请使用已连接的用户列表。在服务器的功能如下:

public RMIClientIntf[] get() throws RemoteException { 
    RMIClientIntf[] users = new RMIClientIntf[openConnections.size()]; 
    /* Fill in users from ClientStruct */ 
    return users; 
} 

如果客户端上,也能实现Serializable接口,那么程序运行,但是当客户机程序调用client1.message(),消息()方法被调用的客户端2和抛出一个空指针在这一点上。

我看这个链接:http://www.exampledepot.com/egs/java.rmi/args_Args.html,这给了我一个提示,它应该实现远程但不序列化按引用传递。我不确定该计划为什么抱怨我的情况。

我真的很感谢任何帮助,我可以得到。我一直在试图解决这个问题一段时间,我似乎无法找到任何解决方案。

非常感谢!

回答

1

您需要导出客户端,并将存根服务器

编辑:这应该工作,应该导出服务器(但不使用rmiregistry中)

server.register((RMIClientIntf) UnicastRemoteObject.exportObject(client,0), name); 
+0

我不知道该怎么做。你有教程吗?我目前有Client.java文件部分的类路径和服务器,客户端和接口项目(其中包含Client.java代码)的代码库。 – Jary

+0

@jary检查编辑 –

+0

非常感谢!我得到它的工作。非常感谢你! – Jary

1

你不能只是通过任意的引用各地通过RMI。客户端必须是要么序列化的,所以它被传递到整个目标,或导出的远程对象本身,这样的远程引用它被通过,它原地踏步 - 即它是一个回调。

编辑:因为后者似乎是你的意图,所有你需要的就是让客户端继承UnicastRemoteObject。

作为Oracle/Sun​​的一部分,有一个很好的RMI Trail。

+0

怎么可能以同样的方式我请自己制作一个导出的远程对象?你有一个简单的教程吗? – Jary

+0

太棒了!我得到它的工作,非常感谢!代码如下:\t \t \t RMIClientIntf stub =(RMIClientIntf)UnicastRemoteObject.exportObject(client,0); \t \t \t String response = server.register(stub,name); – Jary