2012-12-17 61 views
1

我有一个RMI应用程序,详情如下。服务器知道它正在创建DocumentProvider对象,并使用Document接口将对该对象的引用传递给客户端。当客户端将Document对象传递给服务器时,服务器不能再将其转换为DocumentProvider,尽管这是服务器最初创建的。Java RMI远程对象演员/状态

有没有办法做这种类型的转换,即服务器知道它正在创建具有更多内部特性(本例中为InternalClass serverInfo)的Document的特定实现,并且想要在其实现中访问这些附加特性文档函数(在这种情况下,在“doCast()”函数中)。

问另一种方法:一旦服务器创建一个DocumentProvider对象,该对象是坐在服务器上吗?如果是这样,我怎么能给客户一个参考? InternalClass serverInfo;部分不可序列化,并且不能传送给客户端。 (有点像文件句柄等,尽管我可以在DocumentProvider类中保留它并对其进行管理)。

//Interface 
public interface Document extends extends java.rmi.Remote { 
     public String doSomething() throws java.rmi.RemoteException; 
     public String doCast() throws java.rmi.RemoteException; 
} 

//The server: 
    public class DocumentProvider extends java.rmi.server.UnicastRemoteObject implements java.rmi.Remote, Document { 
     InternalClass serverInfo; 

     public String doSomething() throws java.rmi.RemoteException { 
      return "DocumentProvider doing something"; 
     } 
     public String doCast(Document d) throws java.rmi.RemoteException { 
      DocumentProvider d2 = (DocumentProvider) d; // this cast fails, even when d was a DocumentProvider class 
      // then access d.serverInfo, etc. 
     } 
    } 

public interface DocumentFactory extends extends java.rmi.Remote { 
     public Document createDocument() throws java.rmi.RemoteException; 
} 
public class DocumentProvider extends java.rmi.server.UnicastRemoteObject implements java.rmi.Remote, DocumentFactory { 
    public Document createDocument() throws java.rmi.RemoteException { 
     return new DocumentProvider(); 
    } 
} 

//Client app: 
main()... { 
    DocumentFactory dFactory = (lookup/resolve this; this works ok); 
    Document dMain = dFactory.createDocument(); 
    dMain.doCast(dMain); // this fails because 
} 

为了详细说明,“InternalClass serverInfo”是一个不可序列化的第三方“处理”,我必须设法保持其状态的服务器,所以主要问题是如何做到这一点,而返回到基准一个远程对象,允许客户端通过界面中定义的远程调用来“操作”该内部对象。 (另一个简单的例子:如果serverInfo是一个文件句柄,并且我允许客户端通过Document接口执行“查找”和“读取”功能)

回答

1

远程对象被传递并作为存根实现相同的远程接口。因此,投射到实际的远程对象类不可能工作,并且试图远程执行它意义不大。只需使用存根作为接口的一个实例即可。如果这还不够,你的设计就会出现问题。

+0

要详细说明,“InternalClass serverInfo”是一个不可序列化的第三方“句柄”,我必须以某种方式保持其在服务器中的状态,所以主要问题是如何做到这一点,同时返回对远程对象的引用,允许客户端通过界面中定义的远程调用来“操纵”该内部对象。 (另一个简单的例子:如果serverInfo是一个文件句柄,并且我允许客户端通过Document接口执行“查找”和“读取”功能) – Mary

+0

@Mary InternalClass serverInfo与它无关。问题在于Document和DocumentProvider。 'd'是doCast主体中的DocumentProvider是*不可能*。它作为实现Document的远程存根接收。事实上,它由客户端通过createDocument()方式由客户端接收。客户端不需要或不应该需要DocumentProvider。它应该满足于Document。如果不是,您的设计出现问题, – EJP

+0

我可以将DocumentProvider传递给客户端并将其作为服务器中的参数接收吗? (答案似乎是“不”,传递的是一个存根)。这导致回到最初的目标,将远程“处理”传递给客户;更复杂的设计是创建一个整数句柄池,并将服务器对象存储在数组或键值存储中,并将整数句柄传递给客户端。 – Mary