十八,远程部署的RMI

1.RMI( Remote Method Invocation)
	JavaRMI提供客户端和服务器端的辅助设施对象

创建远程服务的步骤
	1.创建Remote接口
		继承java.rmi.Remote   Remote是个接口(接口可以继承其他接口)
		public interface MyRemote extends Remote{
					public String sayHello() throws RemoteException;  //每个远程调用都是有风险的,需要申明异常
			}
			确定返回值都是primitive主数据类型(包括数组和集合)或则实现了Serializable
	2.实现Remote
		这是真正执行的类
		public class MyRemoteImpl extends UnicastRemoteObject implements	MyRemote{
				public String sayHello(){
						return "Service says Hello";
					}
			}
			
			继承 UnicastRemoteObject (让父类处理有关远程的工作)
			
			编写声明RemoteException的无参构造函数
					由于 UnicastRemoteObject的构造函数会抛出RemoteException 所以子类也要声明相同的异常
					public MyRemoteImpl () throws RemoteException{}
			向 RMI registry 注册服务(这里写在了main() 里面)
				try {
					MyRemote service = new MyRemoteImpl();
					Naming.rebind( "Remote Hello", service );  //帮服务命名,客户端会靠名字查询registry
				} catch (Exception ex) {
					 //TODO
				}
	3.用rmic产生stub与skeleton
		%rmic MyRemoteImpl  会产生两个新类  MyRemoteImpl_Stub.class  MyRemoteImpl_Skel.class
	4.启动RMI Registry
		%rmiregistry
	5.启动远程服务
		%java MyRemoteImpl   //是因为我们将启动服务的代码放在了main()中
		
客户端取得stub对象
	1.客户端查询 RMIregister
	Naming.lookup( "rmi://127.0.0.1//Remote Hello" );
	2.RMI registry返回stub 对象
		你必须要有rmic 产生的stub类,否则客户端stub不会被解序列化
		
客户端需要的有  MyRemoteImpl_Stub.class  MyRemote.class Client.class 
服务端需要的有 	MyRemoteImpl_Stub.class MyRemoteImpl_Skel.class	MyRemote.class	MyRemoteImpl.class
2.JINI远程调用
1.类与接口
ServiceServer这个接口实现了Remote	,那是给远程服务用的RMI普通接口
	import java.rmi.*;
	public interface ServiceServer extends Remote{
			Object[] getServiceList() throws RemoteException;
			Service getService( Object serviceKey) throws RemoteException;
		}

2.ServiceServerImpl这个类实现了ServiceServer
	这是实际的RMI远程服务(继承UnicastRemoteObject),它的任务是初始化并存储全部的服务 并把自己登记给RMI registry

3.ServiceBrowser
	这是客户端的类,它创建出简单的GUI,在RMI registry中查询取得ServiceServver的stub, 然后调用它的远程服务取得服务清单并显示在GUI上
4.Service
	这是关键的部分,这个简单的接口只有一个getPanel()方法,每个要传递给客户端的服务都要实现这个接口。
	客户端调用getService( selectedSvc)后取得序列化的对象, 然后调用一定会用的getPanel()来取JPanel,然后放到浏览器上开始与用户交互
	import javax.swing.*;
	import java.io.*;
	public interface Service extends Serializable {
		public JPanel getGuiPanel();
	}

	
远程的实现
import java rmi.*;
import java.util.*;
import java.rmi.server.*;
public class ServiceServerImpl extends UnicastRemoteObject implements ServiceServer{
	HashMap serviceList;  //服务会被存储在集合中
	
	public ServiceServerImpl() throws RemoteException{
			setUpServices();
		}
		
	private void setUpServices(){
			serviceList = new HashMap();
			serviceList.put( "Dice Roolling Service", new DiceService() );
			serviceList.put( "Day of the Week Service", new DayOfTheWeekService() );
			serviceList.put( "Visual Music Service", new MiniMusicService() );
		}
		
		public Object[] getServicesList(){
				System.out.println( "in  remote" );
				return servicesList.keySet().toArray();
			}
		
		public Service getService( Object serviceKey ) throws RemoteException{
			Service theService = (Service) servicesList.get( serviceKey);
			return Service;
		}
		
		public static void main( String[] args ){
				try {
						Naming.rebind( "ServiceServer", new ServiceServerImpl() );
				} catch (Exception ex) {
					 ex.printStackTrace();
				}
				System.out.println( "Remote service is running");
			}
}


客户端的调用
import java.awt;
import javax.swing.*;
import	java.rmi.*;
import	java.awt.event.*;

public class ServiceBrowser{
	JPanel mainPanel;
	JComboBox serviceList;
	ServiceService server;
	
	public void buidGUI(){
			JFrame frame = new JFrame( "RMI Browser");
			mainPanel = new JPanel();
			frame.getContentPane().add( BroderLayout.CENTER, mainPanel );
			Object[] services = getServicesList();
			
			ServiceList = new JComboBox( services ); //JComboBox知道如何显示数组中的字符串
			serviceList.addActionListener( new MyListListener() );
			frame.setSize( 500, 500 );
			frame.setVisible( true );
		}
		
		void loadService( Object serviceSelection ){
				try {
						Service svc = server.getService( serviceSelection );
						
						mainPanel.removeAll();
						mainPanel.add( svc.getGuiPanel() );
						mainPanel.validate();
						mainPanel.repaint();
				} catch (Exception ex) {
					 ex.printStackTrace();
				}
			}
		Object[] getServicesList(){
				Object obj = null;
				Object[] services = null;
				try {
					obj = Naming.lookup( "rmi://127.0.0.1/ServiceServer" );
				} catch (Exception ex) {
					 ex.printStackTrace();
				}
				
				server = (ServiceServer)obj;
				
				try {
						services = server.getServicesList();
				} catch (Exception ex) {
					ex.printStackTrace(); 
				}
				
				return services;
			}
		
	class MyListListener implements ActionListener{
			public void actionPerformed( ActionEvent ev){
					Object selection = serviceList.getSelectedItem();
					loadService(selection);
				}
		}
		
	public static void main( String[] args ){
			new ServiceBrowser().buidGUI();
		}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值