溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java RMI遠程調(diào)用的案例

發(fā)布時間:2021-02-19 11:31:36 來源:億速云 閱讀:394 作者:小新 欄目:編程語言

這篇文章主要介紹Java RMI遠程調(diào)用的案例,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

我們先來看看Java RMI的定義:

RMI(Remote Method Invocation,遠程方法調(diào)用)是用Java在JDK1.2中實現(xiàn)的,它大大增強了Java開發(fā)分布式應(yīng)用的能力。Java作為一種風(fēng)靡一時的網(wǎng)絡(luò)開發(fā)語言,其巨大的威力就體現(xiàn)在它強大的開發(fā)分布式網(wǎng)絡(luò)應(yīng)用的能力上,而RMI就是開發(fā)百分之百純Java的網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)的核心解決方案之一。其實它可以被看作是RPC的Java版本。但是傳統(tǒng)RPC并不能很好地應(yīng)用于分布式對象系統(tǒng)。而Java RMI 則支持存儲于不同地址空間的程序級對象之間彼此進行通信,實現(xiàn)遠程對象之間的無縫遠程調(diào)用。

RMI遠程調(diào)用步驟

RMI的交互圖:

Java RMI遠程調(diào)用的案例

RMI由3個部分構(gòu)成,第一個是rmiregistry(JDK提供的一個可以獨立運行的程序,在bin目錄下),第二個是server端的程序,對外提供遠程對象,第三個是client端的程序,想要調(diào)用遠程對象的方法。
首先,先啟動rmiregistry服務(wù),啟動時可以指定服務(wù)監(jiān)聽的端口,也可以使用默認的端口(1099)。
其次,server端在本地先實例化一個提供服務(wù)的實現(xiàn)類,然后通過RMI提供的Naming/Context/Registry(下面實例用的Registry)等類的bind或rebind方法將剛才實例化好的實現(xiàn)類注冊到rmiregistry上并對外暴露一個名稱。
最后,client端通過本地的接口和一個已知的名稱(即rmiregistry暴露出的名稱)再使用RMI提供的Naming/Context/Registry等類的lookup方法從RMIService那拿到實現(xiàn)類。這樣雖然本地沒有這個類的實現(xiàn)類,但所有的方法都在接口里了,便可以實現(xiàn)遠程調(diào)用對象的方法了。

存根和骨干網(wǎng)的具體通信過程:

Java RMI遠程調(diào)用的案例

方法調(diào)用從客戶對象經(jīng)存根(stub)、遠程引用層(Remote Reference Layer)和傳輸層(Transport Layer)向下,傳遞給主機,然后再次經(jīng)傳輸層,向上穿過遠程調(diào)用層和骨干網(wǎng)(Skeleton),到達服務(wù)器對象。
存根扮演著遠程服務(wù)器對象的代理的角色,使該對象可被客戶激活。
遠程引用層處理語義、管理單一或多重對象的通信,決定調(diào)用是應(yīng)發(fā)往一個服務(wù)器還是多個。
傳輸層管理實際的連接,并且追蹤可以接受方法調(diào)用的遠程對象。
骨干網(wǎng)完成對服務(wù)器對象實際的方法調(diào)用,并獲取返回值。
返回值向下經(jīng)遠程引用層、服務(wù)器端的傳輸層傳遞回客戶端,再向上經(jīng)傳輸層和遠程調(diào)用層返回。最后,存根獲得返回值。

JAVA RMI簡單示例

本示例是client端調(diào)用server端遠程對象的加減法方法,具體步驟為:
1. 定義一個遠程接口

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * 必須繼承Remote接口。
 * 所有參數(shù)和返回類型必須序列化(因為要網(wǎng)絡(luò)傳輸)。
 * 任意遠程對象都必須實現(xiàn)此接口。
 * 只有遠程接口中指定的方法可以被調(diào)用。
 */
public interface IRemoteMath extends Remote {

  	// 所有方法必須拋出RemoteException
	public double add(double a, double b) throws RemoteException;
	public double subtract(double a, double b) throws RemoteException;
	
}

(學(xué)習(xí)視頻分享:java視頻教程)

2. 遠程接口實現(xiàn)類

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import remote.IRemoteMath;

/**
 * 服務(wù)器端實現(xiàn)遠程接口。
 * 必須繼承UnicastRemoteObject,以允許JVM創(chuàng)建遠程的存根/代理。
 */
public class RemoteMath extends UnicastRemoteObject implements IRemoteMath {

	private int numberOfComputations;
	
	protected RemoteMath() throws RemoteException {
		numberOfComputations = 0;
	}
	
	@Override
	public double add(double a, double b) throws RemoteException {
		numberOfComputations++;
		System.out.println("Number of computations performed so far = " 
				+ numberOfComputations);
		return (a+b);
	}

	@Override
	public double subtract(double a, double b) throws RemoteException {
		numberOfComputations++;
		System.out.println("Number of computations performed so far = " 
				+ numberOfComputations);
		return (a-b);
	}

}

3. 服務(wù)器端

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import remote.IRemoteMath;

/**
 * 創(chuàng)建RemoteMath類的實例并在rmiregistry中注冊。
 */
public class RMIServer {

	public static void main(String[] args)  {
		
		try {
			// 注冊遠程對象,向客戶端提供遠程對象服務(wù)。
			// 遠程對象是在遠程服務(wù)上創(chuàng)建的,你無法確切地知道遠程服務(wù)器上的對象的名稱,
			// 但是,將遠程對象注冊到RMI Registry之后,
			// 客戶端就可以通過RMI Registry請求到該遠程服務(wù)對象的stub,
			// 利用stub代理就可以訪問遠程服務(wù)對象了。
			IRemoteMath remoteMath = new RemoteMath();  
			LocateRegistry.createRegistry(1099);    
			Registry registry = LocateRegistry.getRegistry();
			registry.bind("Compute", remoteMath);
			System.out.println("Math server ready");
			// 如果不想再讓該對象被繼續(xù)調(diào)用,使用下面一行
			// UnicastRemoteObject.unexportObject(remoteMath, false);
		} catch (Exception e) {
			e.printStackTrace();
		}		
		
	}
	
}

4. 客戶端

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import remote.IRemoteMath;

public class MathClient {

	public static void main(String[] args) {
		
		try { 
			// 如果RMI Registry就在本地機器上,URL就是:rmi://localhost:1099/hello
			// 否則,URL就是:rmi://RMIService_IP:1099/hello
			Registry registry = LocateRegistry.getRegistry("localhost");        
			// 從Registry中檢索遠程對象的存根/代理
			IRemoteMath remoteMath = (IRemoteMath)registry.lookup("Compute");
			// 調(diào)用遠程對象的方法
			double addResult = remoteMath.add(5.0, 3.0);
			System.out.println("5.0 + 3.0 = " + addResult);
			double subResult = remoteMath.subtract(5.0, 3.0);
			System.out.println("5.0 - 3.0 = " + subResult);			
		}catch(Exception e) {
			e.printStackTrace();
		}
				
	}
	
}

結(jié)果如下:

server端

Java RMI遠程調(diào)用的案例

client端

Java RMI遠程調(diào)用的案例

以上是“Java RMI遠程調(diào)用的案例”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI