定义接口
import java.rmi.*;
public interface Warehouse extends Remote {
//必须继承Remote接口
//所有方法必须声明抛出RemoteException异常。
double getPrice(String description) throws RemoteException;
}
-------------------
定义服务端的代码
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
public class WarehoseImpl extends UnicastRemoteObject implements Warehouse {
private Map<String, Double> prices;
public WarehoseImpl() throws RemoteException {
prices = new HashMap<String, Double>();
prices.put("Blackwell Toaster", 24.95);
prices.put("ZapXpress Microwave Oven", 49.95);
}
public double getPrice(String description) throws RemoteException {
Double price = prices.get(description);
return price == null ? 0 : price;
}
}
---
RMI的URL格式:
rmi://regserver.mycompany.com:99/central_warehouse
默认情况下:主机名是localhost,端口号为1099.
看下面的例子
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
public class WarehoseImpl extends UnicastRemoteObject implements Warehouse {
private Map<String, Double> prices;
public WarehoseImpl() throws RemoteException {
prices = new HashMap<String, Double>();
prices.put("Blackwell Toaster", 24.95);
prices.put("ZapXpress Microwave Oven", 49.95);
}
public double getPrice(String description) throws RemoteException {
Double price = prices.get(description);
return price == null ? 0 : price;
}
public static void main(String[] args) {
try {
WarehoseImpl centralWarehouse = new WarehoseImpl();
Context namingContext = new InitialContext();
namingContext.bind("rmi:central_warehouse", centralWarehouse);
} catch (Exception e) {
}
}
}
基于安全原因,一个应用只有当它与注册表运行在同一个服务器时,
该应用才可以绑定,取消绑定,或者重新绑定注册对象的引用。
===================================================
碰到一些问题,解决了,
献上最终可运行版代码:
import java.rmi.*;
public interface Warehouse extends Remote {
//必须继承Remote接口
//所有方法必须声明抛出RemoteException异常。
double getPrice(String description) throws RemoteException;
}
---
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
public class WarehoseImpl extends UnicastRemoteObject implements Warehouse {
private Map<String, Double> prices;
public WarehoseImpl() throws RemoteException {
prices = new HashMap<String, Double>();
prices.put("Blackwell Toaster", 24.95);
prices.put("ZapXpress Microwave Oven", 49.95);
}
public double getPrice(String description) throws RemoteException {
Double price = prices.get(description);
return price == null ? 0 : price;
}
}
---
import java.rmi.RemoteException;
import java.util.Enumeration;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
public class WarehouseClient {
public static void main(String[] args) throws NamingException,
RemoteException {
Context namingContext = new InitialContext();
Enumeration<NameClassPair> e = namingContext.list("rmi://192.168.2.1:8080/");
while (e.hasMoreElements()) {
System.out.println(e.nextElement().getName());
}
//
String url = "rmi://192.168.2.1:8080/central_warehouse";
Warehouse centralWarehouse = (Warehouse) namingContext.lookup(url);
if(null==centralWarehouse){
System.out.println("fail to find remote RMI server...");
return;
}
String descr = "Blackwell Toaster";
double price = centralWarehouse.getPrice(descr);
System.out.println(descr + ": " + price);
}
}
---
import java.rmi.registry.LocateRegistry;
import javax.naming.Context;
import javax.naming.InitialContext;
public class WarehouseServer {
public static void main(String[] args) {
//在服务器端的容器内注册此对象
//注意:当服务器有多个IP时,client连接时会有问题。典型的服务器有多个 ip 引起的 rmi 连接问题。
//参考:http://blog.csdn.net/model_cz/article/details/6525029
// http://wenku.baidu.com/link?url=7CKpdI0KBYrIzdQyfDqAiR4HKP43mwxbHw_28UWuusXjXJAO3qS9dwwKh3_rlGsghxD40Bksbh8bSqGQCY1J6jaMXQsFsOmAOmWS7dPYTJO
try {
//下面几行很重要
System.setProperty("java.rmi.server.hostname" , "192.168.2.1" );//指定监听IP(当服务器有多个IP时)
LocateRegistry.createRegistry(8080); (指定服务器的监听端口)
WarehoseImpl centralWarehouse = new WarehoseImpl();
Context namingContext = new InitialContext();
namingContext.bind("rmi://192.168.2.1:8080/central_warehouse", centralWarehouse);
} catch (Exception e) {
System.out.println(e.toString());
return;
}
System.out.println("waiting for the client to connect...");
}
}
---
如果为了绑定数据通信端口,则
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.server.RMISocketFactory;
public class WareFactory extends RMISocketFactory{
public Socket createSocket(String host, int port)
throws IOException{
//System.out.println("ok,a client connection is established...port:"+port +" host:"+host);
return new Socket(host,port);
}
public ServerSocket createServerSocket(int port)
throws IOException {
System.out.println("createServerSocket: port is "+port);
if (port == 0)
port = 8081;
return new ServerSocket(port);
}
}
然后在server里调用
//指定数据连接端口
RMISocketFactory.setSocketFactory(new WareFactory());