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