JAVA远程调用之RMI

定义接口

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()); 

 

 

你可能感兴趣的:(rmi)