假设您在 RMI 中有以下内容:
这是远程接口:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote
{
String sayHello() throws RemoteException;
}
这是服务器实现代码:(它实现了接口)
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.net.*;
public class Server implements Hello {
public Server() {}
public String sayHello()
{
return "Hello, world!";
}
public static void main(String args[])
{
try
{
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("HelloServer", stub);
System.err.println("Server ready");
} catch (Exception e)
{
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
这是客户端代码:
import java.rmi.*;
import java.rmi.server.*;//////note additional imports
import java.io.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.net.*;
public class HelloClient2 {
private HelloClient2() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {/////note this addition
RMISocketFactory.setSocketFactory(new sun.rmi.transport.proxy.RMIHttpToCGISocketFactory());
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("HelloServer");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
现在我想创建一个连接到 rmi 服务器的 Objective-C 客户端。为了能够调用 rmi 服务器上的方法,我在 apache web 服务器上创建了一个代理,它将 RMI 调用嵌入到 HTTP 请求中。
客户端中的行:RMISocketFactory.setSocketFactory(new sun.rmi.transport.proxy.RMIHttpToCGISocketFactory()); 负责 RMI 隧道(在 http 请求中传递 RMI 调用)。所以基本上这一行创建了一个 http post 请求的形式
http://localhost:80/cgi-bin/java-rmi?forward=portnum
其中 portnum 是服务器远程对象的端口(匿名)
这是什么意思?这意味着应该有一个 Web 服务器在 localhost 上的端口 80 上进行侦听。我们有理想的 apache tomcat Web 服务器监听 8080,但我们将其端口更改为 80。
解决了,我们仍然需要处理 url 的其余部分。所以在 tomcat 的 web 应用中,我们创建了一个名为 cgi-bin 的新目录。cgi-bin 有一个 WEB-INF 目录,其中包含一个 classes 目录和一个 web.xml 文件。在 classes 目录中,我们添加了服务器和客户端的编译类以及 servlet 处理程序。servlet 处理程序接收 http post 请求,获取 rmi 调用并将它们转发到 rmi 服务器。
如何让 web 服务器知道他应该调用 servlet 处理程序?在 web.xml 文件中,我们为该 servlet 添加了一个条目,其名称为 ServletHandler(类的名称)和一个 url 映射:/java-rmi。这样本地主机就知道将请求转发到哪里。正如我之前所说,一旦 servlet 处理程序接收到请求,它将处理它并将其发送到 rmi 服务器。
现在我的问题是这些:
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("HelloServer");
我根本不知道如何定位注册表并在 Objective-C 中查找以找到远程对象。(存根是远程对象的本地引用)
而且我不认为可以使用代理来完成,代理专门用于处理定向到 rmi 服务器的请求。因此,为了测试 servlet,需要调用某个远程方法,例如在服务器中实现的 sayHello()。与注册表相关的东西不是远程方法调用。
那么我如何在 Objective-C 中处理这些?