使用JAVA中RMI机制来实现分布式程序(2)
摘一段分布式系统中的例子代码:(http://www.cdk5.net/wp/extra-material/supplementary-material-for-chapter-5)
(但经过本人亲测,此代码还是有问题的,主要是涉及
System.setSecurityManager(new RMISecurityManager());这句无法真正起作用,所以还是建议参看前两篇的文章中的方法!
)
这里最主要的学习点就是一旦完成了这种RMI机制,在服务器端和客户端可以实现callback的机制时,可以跨位置(进程)调用类。就是说如果服务器端
需要实例化一个客户端定义的类也是完全可以的,这个时候将在整个分布式系统中需要相应的类定义,所以可以讲客户端的代码“下载”到服务器端!
1:
package examples.RMIShape; import java.rmi.*; import java.util.Vector; public interface Shape extends Remote { int getVersion() throws RemoteException; GraphicalObject getAllState() throws RemoteException; }
2:
package examples.RMIShape; import java.rmi.*; import java.util.Vector; public interface ShapeList extends Remote { Shape newShape(GraphicalObject g) throws RemoteException; Vector allShapes()throws RemoteException; int getVersion() throws RemoteException; }
3:
package examples.RMIShape; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class ShapeListServer { public static void main(String args[]){ System.setSecurityManager(new RMISecurityManager()); try{ ShapeList aShapelist = new ShapeListServant(); ShapeList stub = (ShapeList) UnicastRemoteObject.exportObject(aShapeList,0); Naming.rebind("ShapeList", aShapelist); System.out.println("ShapeList server ready"); }catch(Exception e) { System.out.println("ShapeList server main " + e.getMessage()); } } }
:4:
package examples.RMIShape; import java.util.Vector; public class ShapeListServant implements ShapeList{ private Vector theList; private int version; public ShapeListServant()throws RemoteException{ theList = new Vector(); version = 0; } public Shape newShape(GraphicalObject g) throws RemoteException{ version++; Shape s = new ShapeServant( g, version); theList.addElement(s); return s; } public Vector allShapes()throws RemoteException{ return theList; } public int getVersion() throws RemoteException{ return version; } }
:5:
package examples.RMIShape; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class ShapeServant extends UnicastRemoteObject implements Shape { int myVersion; GraphicalObject theG; public ShapeServant(GraphicalObject g, int version)throws RemoteException{ theG = g; myVersion = version; } public int getVersion() throws RemoteException { return myVersion; } public GraphicalObject getAllState() throws RemoteException{ return theG; } }
6:
package examples.RMIShape; import java.rmi.*; import java.rmi.server.*; import java.util.Vector; import java.awt.Rectangle; import java.awt.Color; public class ShapeListClient{ public static void main(String args[]){ String option = "Read"; String shapeType = "Rectangle"; if(args.length > 0) option = args[0]; // read or write if(args.length > 1) shapeType = args[1]; // specify Circle, Line etc System.out.println("option = " + option + "shape = " + shapeType); if(System.getSecurityManager() == null){ System.setSecurityManager(new RMISecurityManager()); } else System.out.println("Already has a security manager, so cant set RMI SM"); ShapeList aShapeList = null; try{ aShapeList = (ShapeList) Naming.lookup("//Jean.torriano.net/ShapeList"); System.out.println("Found server"); Vector sList = aShapeList.allShapes(); System.out.println("Got vector"); if(option.equals("Read")){ for(int i=0; i<sList.size(); i++){ GraphicalObject g = ((Shape)sList.elementAt(i)).getAllState(); g.print(); } } else { GraphicalObject g = new GraphicalObject(shapeType, new Rectangle(50,50,300,400),Color.red, Color.blue, false); System.out.println("Created graphical object"); aShapeList.newShape(g); System.out.println("Stored shape"); } }catch(RemoteException e) {System.out.println("allShapes: " + e.getMessage()); }catch(Exception e) {System.out.println("Lookup: " + e.getMessage());} } }
:7:
package examples.RMIShape; import java.awt.Rectangle; import java.awt.Color; import java.io.Serializable; public class GraphicalObject implements Serializable{ public String type; public Rectangle enclosing; public Color line; public Color fill; public boolean isFilled; // constructors public GraphicalObject() { } public GraphicalObject(String aType, Rectangle anEnclosing, Color aLine,Color aFill, boolean anIsFilled) { type = aType; enclosing = anEnclosing; line = aLine; fill = aFill; isFilled = anIsFilled; } public void print(){ System.out.print(type); System.out.print(enclosing.x + " , " + enclosing.y + " , " + enclosing.width + " , " + enclosing.height); if(isFilled) System.out.println("- filled");else System.out.println("not filled"); } }