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 通信过程,需要建立多个虚拟机作为客户端

posted @ 2024-10-13 17:06  江水为竭  阅读(11)  评论(0编辑  收藏  举报