RMI分布式通信及其应用
分布式系统实验一
RMI分布式通信及其应用
实验名称:RMI分布式通信及其应用
实验要求:利用RMI通讯机制,完成一个分布式通讯应用。
实验学时:2学时。
实验内容:
设计一个基于Java RMI通讯机制的在线拍卖系统。系统客户端(买家)通过服务器(拍卖中心)出价竞拍商品,实现客户端和服务器之间的交互。
系统设计要求:
(1)服务器(拍卖中心):负责管理拍卖物品,记录出价和买家姓名,并通知所有注册的客户端当前的最高出价。
(2)客户端(买家):可以查看当前拍卖的物品名称和价格,然后输入买家姓名,进行出价。
代码结构:
1. Auction 接口
接口继承自 Remote,使得其方法可以从远程客户端调用。定义了拍卖相关的方法如placeBid和getCurrentBid。
2. AuctionImpl类
实现远程接口,继承自UnicastRemoteObject类,以确保其实例可以被远程访问。实现了placeBid和getCurrentBid方法,具体实现了拍卖功能。
3. AuctionServer类
包含main方法的服务器端程序。在该类中,需要创建AuctionImpl类的一个实例,并且启动RMI注册表,并将实例绑定到名为"Auction"的远程对象注册中。
4. AuctionClient类
包含main方法的客户端程序。在该类中,需要连接到RMI注册表,并获取"Auction"远程对象的存根(stub),然后通过命令行界面提供用户界面,使用户能够查看物品的当前出价并进行出价操作。
运行结果:
启动服务端:
启动客户端:
在一个客户端发起出价,另一个客户端查询。
轮流出价,查询。
遇到的问题:
在IntelliJ IDEA中运行测试,需要运行多个Client端实例,再次点击运行后会提示“是否重新运行”。
解决:将如下设置打开,就可以运行多个Client端实例。
RMI:
RMI(Remote Method Invocation)远程方法调用,Java RMI 在 JDK1.1 中实现, 支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的 无缝远程调用,是网络分布式应用系统的核心解决方案之一。
RMI 目前使用 Java 远程消息交换协议 JRMP(Java Remote Messaging Protocol) 进行通信。用 Java RMI 开发的应用系统可以部署在任何支持 JRE(Java Run Environment Java,运行环境)的平台上。但由于 JRMP 是专为 Java 对象制定的, 因此,RMI 对于用非 Java 语言开发的应用系统的支持不足,不能与用非 Java 语 言书写的对象进行通信。
提示:
一、实验中的应用案例
1. 逻辑关系
首先有一个共同的协议(即远程接口),然后实现这个接口,然后在服务端 注册这个实现的实例,最后客户端才能找到并使用这些远程对象。在整个过程中, 接口作为客户端和服务端之间的合同,保证了双方可以通过预定的方式进行有效 的通信。
2. 实现步骤
以在线拍卖应用为例,部分代码提示如下,
(1)接口定义:定义了必要的远程接口,接口继承自 Remote,使得其方法 可以从远程客户端调用。
package com.hit.java.auction; import java.rmi.Remote; import java.rmi.RemoteException; //定义一个 Auction 接口,该接口包括方法来出价和获取当前最高出价
public interface Auction extends Remote { boolean placeBid(String itemID, double bid, String bidderName) throws RemoteException; String getCurrentBid(String itemID) throws RemoteException; }
(2)实现远程接口 AuctionImpl 类:实现了 Auction 接口的类 AuctionImpl, 此类继承自 UnicastRemoteObject,使得其实例可以被远程访问。内部使用两个 哈希图分别存储当前的最高出价和相应的出价者。
package com.hit.java. auction; import java.rmi.server.UnicastRemoteObject; import java.rmi.RemoteException; import java.util.HashMap; import java.util.Map; //实现 Auction 接口。该实现将保存当前的最高出价并通知所有注册的客户端。 public class AuctionImpl extends UnicastRemoteObject implements Auction { private Map currentBids; private Map highestBidder; protected AuctionImpl() throws RemoteException { super(); currentBids = new HashMap<>(); highestBidder = new HashMap<>(); } @Override public synchronized boolean placeBid(String itemID, double bid, String bidderName) throws RemoteException { 如果提供的出价高于当前记录的最高出价,则更新记录,并返回 true;否则返回 false; } @Override public synchronized String getCurrentBid(String itemID) throws RemoteException { 返回指定物品的最高出价及出价者信息; }
}
(3)AuctionServer 类。创建包含 main 方法的服务器端程序,创建 AuctionImpl 的一个实例,然后创建设置并启动了 RMI 注册表。负责创建和注册 RMI 服务,使其能够接受客户端的远程调用。
package com.hit.java.auction; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; //服务器程序将创建和注册远程对象。
public class AuctionServer { public static void main(String[] args) { 创建 AuctionImpl 实例; 启动 RMI 注册表; 该实例绑定到名为 "Auction" 的远程对象注册中; 打印服务器状态; }
}
(4)AuctionClient 类。开发包含 main 方法的客户端程序。允许用户与远程 拍卖服务进行交互,提交出价或查询当前出价。
package com.hit.java.auction; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.util.Scanner; //客户端程序将允许用户查看当前的最高出价和进行出价。
public class AuctionClient { public static void main(String[] args) { 连接到 RMI 注册表,与服务端建立连接; 查找并获取 "Auction" 远程对象的存根(stub); 通过命令行界面,提供用户界面,用户可以查看物品的当前出价并进行出价操作; }
}
程序先启动服务端,然后启动客户端。整个系统通过这四部分协同工作,实 现了一个分布式的远程系统。这个示例只有一个客户端,如果想查看多客户端的 RMI 通信过程,需要建立多个虚拟机作为客户端
本文来自博客园,作者:江水为竭,转载请注明原文链接:https://www.cnblogs.com/Az1r/p/18462560