Remote Method Invocation (RMI)
Remote Method Invocation (RMI)
Client-Server Communication Sockets Remote Procedure Calls Remote Method Invocation (Java)
Sockets
A socket is defined as an endpoint for communication. Concatenation of IP address and port The socket 161.25.19.8:1625 refers to port 1625 on host 161.25.19.8 Communication consists between a pair of sockets. Considered a low-level form of communication between distributed processes.
Sockets allow only an unstructured stream of bytes to be exchanged. It is the responsibility of the client or server application to impose a structure on the data.
Socket Communication
Remote Procedure Calls Remote procedure call (RPC) abstracts procedure calls between processes on networked systems. Stub client-side proxy for the actual procedure on the server. Server has a similar stub as well. The client-side stub locates the server and marshals the parameters. The server-side stub receives this message, unpacks the marshaled parameters, and performs the procedure on the server. External data representation (XDR) I.e mostsignificant (big-endian), least-significant(littleendian)
Execution of RPC
Marshalling Parameters
Marshalling of data
Can transfer objects as well Class ObjectOutputStream converts Serializable object into stream of bytes Transmit across network Class ObjectInputStream reconstructs object
Case Study: Creating a Distributed System with RMI Four major steps
Define remote interface
Describes client/server communication
1// Fig. 20.1: TemperatureServer.java 2// TemperatureServer interface definition 3import java.rmi.*; 4 5public interface TemperatureServer extends Remote { 6 7 8} public WeatherInfo[] getWeatherInfo() throws RemoteException;
UnicastRemoteObject
Provides functionality for remote objects Constructor exports object so it can receive remote calls Wait for client on anonymous port number
22 public TemperatureServerImpl() throws RemoteException
URL object
Contains URL for Traveler's Forecast web page Throws MalformedURLException
InputStreamReader
Translates bytes to Unicode characters
BufferedReader
Buffers characters Method readLine Returns one line as a String
WeatherInfo objects
City name, temperature, description of weather Method substring to extract data from line Store all WeatherInfo objects in a Vector
84 85 weatherInformation[ i ] = ( WeatherInfo ) cityVector.elementAt( i );
Close connection
1// Fig. 20.1: TemperatureServer.java 2// TemperatureServer interface definition 3import java.rmi.*; 4 5public interface TemperatureServer extends Remote { 6 7 8} 9TemperatureServer interface. 10 // Fig. 20.2: TemperatureServerImpl.java public WeatherInfo[] getWeatherInfo() throws RemoteException;
11 // TemperatureServerImpl definition
12 import java.rmi.*; 13 import java.rmi.server.*; 14 import java.util.*; 15 import java.io.*; 16 import java.net.*; 17 18 public class TemperatureServerImpl extends UnicastRemoteObject 19 20 21 22 23 24 25 26 27 } public TemperatureServerImpl() throws RemoteException { super(); updateWeatherConditions(); implements TemperatureServer { private WeatherInfo weatherInformation[];
Superclass constructor exports objects, and this constructor must be able to throw RemoteException.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
// get weather information from NWS private void updateWeatherConditions() throws RemoteException { try { System.err.println( "Updating weather information..." );
// Traveler's Forecast Web Page URL url = new URL( "http://iwin.nws.noaa.gov/iwin/us/traveler.html" ); BufferedReader in = new BufferedReader( new InputStreamReader( url.openStream() ) ); String separator = "</PRE><HR> <BR><PRE>";
// locate first horizontal line on Web pageconnection to file. Open while ( !in.readLine().startsWith( separator ) ) InputStreamReader formats it to Unicode ; // do nothing characters, and BufferedReader buffers the // s1 is the day format and s2 is the night format String s1 = "CITY WEA HI/LO WEA HI/LO"; readLine until separator String s2 = "CITY WEA LO/HI WEA LO/HI"; String inputLine = "";
characters.
found.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
// locate header that begins weather information do { inputLine = in.readLine(); } while ( !inputLine.equals( s1 ) && !inputLine.equals( s2 ) ); Create WeatherInfo
object, add data 2.4 Locate header (substring), add to Vector . Loop until blank line reached. 2.5 Loop 2.5.1 WeatherInfo 2.5.2 readLine
inputLine = in.readLine();
while ( !inputLine.equals( "" ) ) { // create WeatherInfo object for city WeatherInfo w = new WeatherInfo( inputLine.substring( 0, 16 ), inputLine.substring( 16, 22 ), inputLine.substring( 23, 29 ) ); cityVector.addElement( w ); // add to Vector inputLine = in.readLine(); // get next city's info } // create array to return to client weatherInformation = new WeatherInfo[ cityVector.size() ];
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
System.err.println( "Finished Processing Data." ); in.close(); // close connection to NWS server } catch( java.net.ConnectException ce ) { System.err.println( "Connection failed." ); System.exit( 1 ); } catch( Exception e ) { e.printStackTrace(); System.exit( 1 ); } }
4.1 temp
// implementation for TemperatureServer interface method public WeatherInfo[] getWeatherInfo() { return weatherInformation; } public static void main( String args[] ) throws Exception { System.err.println( "Initializing server: please wait." ); // create server object TemperatureServerImpl temp = new TemperatureServerImpl();
// bind TemperatureServerImpl object to the rmiregistry String serverObjectName = "//localhost/TempServer"; Naming.rebind( serverObjectName, temp ); System.err.println( "The Temperature Server is up and
121 }
1/ Fig. 20.3: WeatherInfo.java 2// WeatherInfo class definition This allows objects to be passed as a 3import java.rmi.*; stream of bytes. 4import java.io.Serializable; 5 6public class WeatherInfo implements Serializable { 7 private String cityName; 8 private String temperature; 9 private String description; 10 11 public WeatherInfo( String city, String desc, String temp ) 12 { 13 cityName = city; 14 temperature = temp; 15 description = desc; 16 } 17 18 public String getCityName() { return cityName; } 19 20 public String getTemperature() { return temperature; } 21 22 public String getDescription() { return description; } 23 }
1. Instance variables
1.1 Constructor 2. Get methods
Add WeatherItems
Initialize with WeatherInfo
68 69 70 74 75 76 77 public static void main( String args[] ) { TemperatureClient gt = null; if ( args.length == 0 ) gt = new TemperatureClient( "localhost" ); else gt = new TemperatureClient( args[ 0 ] );
main
Passes command line argument (ip) to constructor localhost default
1// Fig. 20.4: TemperatureClient.java 2// TemperatureClient definition 3import java.awt.*; 4import java.awt.event.*; 5import javax.swing.*; 1. import 6import java.rmi.*; 7 8public class TemperatureClient extends JFrame 1.1 Constructor 9{ 10 public TemperatureClient( String ip ) 2. getRemoteTemp 11 { 12 super( "RMI TemperatureClient..." ); 13 getRemoteTemp( ip ); 2.1 14 serverObjectName 15 setSize( 625, 567 ); 16 setResizable( false ); Use ip specified at command line. 17 show(); 2.2 Naming.lookup 18 } 19 Lookup remote object in 20 // obtain weather information from TemperatureServerImpl registry. Returns Remote 21 // remote object 22 private void getRemoteTemp( String ip ) reference, cast to proper 23 { type. 24 try { 25 // name of remote server object bound to rmi registry 26 String serverObjectName = "//" + ip + "/TempServer"; 27 28 // lookup TemperatureServerImpl remote object 29 // in rmiregistry 30 TemperatureServer mytemp = ( TemperatureServer ) 31 Naming.lookup( serverObjectName );
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 // get weather information from server WeatherInfo weatherInfo[] = mytemp.getWeatherInfo(); WeatherItem w[] = new WeatherItem[ weatherInfo.length ]; ImageIcon headerImage = new ImageIcon( "images/header.jpg" ); JPanel p = new JPanel();
// determine number of rows for the GridLayout; // add 3 to accommodate the two header JLabels // and balance the columns p.setLayout( new GridLayout( ( w.length + 3 ) / 2, 2 ) ); p.add( new JLabel( headerImage ) ); // header 1 p.add( new JLabel( headerImage ) ); // header 2
for ( int i = 0; i < w.length; i++ ) { w[ i ] = new WeatherItem( weatherInfo[ i ] ); p.add( w[ i ] ); } getContentPane().add( new JScrollPane( p ), BorderLayout.CENTER ); } catch ( java.rmi.ConnectException ce ) { System.err.println( "Connection to server failed. " + "Server may be temporarily unavailable." ); }
2.4.1 WeatherItem
62 63 64 65
66
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 }
}
public static void main( String args[] ) { TemperatureClient gt = null; // if no sever IP address or host name specified, // use "localhost"; otherwise use specified host if ( args.length == 0 ) gt = new TemperatureClient( "localhost" ); else gt = new TemperatureClient( args[ 0 ] ); gt.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } ); }
1// Fig. 20.5: WeatherItem.java 2// WeatherItem definition 3import java.awt.*; 4import javax.swing.*; 5 1. Class WeatherItem 6public class WeatherItem extends JLabel { 7 private static ImageIcon weatherImages[], backgroundImage; 1.1 static variables 8 private final static String weatherConditions[] = 9 { "SUNNY", "PTCLDY", "CLOUDY", "MOCLDY", "TSTRMS", 10 "RAIN", "SNOW", "VRYHOT", "FAIR", "RNSNOW", 1.2 Initializer block 11 "SHWRS", "WINDY", "NOINFO", "MISG" }; 12 private final static String weatherImageNames[] = 13 { "sunny", "pcloudy", "mcloudy", "mcloudy", "rain", 1.3 Load ImageIcons 14 "rain", "snow", "vryhot", "fair", "rnsnow", 15 "showers", "windy", "noinfo", "noinfo" }; 16 17 // static initializer block to load weather images 18 static { 19 backgroundImage = new ImageIcon( "images/back.jpg" ); 20 weatherImages = 21 new ImageIcon[ weatherImageNames.length ]; 22 23 for ( int i = 0; i < weatherImageNames.length; ++i ) 24 weatherImages[ i ] = new ImageIcon( 25 "images/" + weatherImageNames[ i ] + ".jpg" ); 26 } 27 28 // instance variables Use names in weatherImageNames 29 private ImageIcon weather; array to load ImageIcons. 30 private WeatherInfo weatherInfo;
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
public WeatherItem( WeatherInfo w ) { weather = null; weatherInfo = w; // locate image for city's weather condition for ( int i = 0; i < weatherConditions.length; ++i ) if ( weatherConditions[ i ].equals( weatherInfo.getDescription().trim() ) ) { weather = weatherImages[ i ]; break; Loop though } // // // if
pick the "no info" image if either there is no weather info or no image for the current weather condition ( weather == null ) { weather = weatherImages[ weatherImages.length - 1 ]; System.err.println( "No info for: " + weatherInfo.getDescription() );
60 61 62 63 64
Font f = new Font( "SansSerif", Font.BOLD, 12 ); g.setFont( f ); g.setColor( Color.white ); g.drawString( weatherInfo.getCityName(), 10, 19 ); g.drawString( weatherInfo.getTemperature(), 130, 19 ); weather.paintIcon( this, g, 253, 1 ); } // make WeatherItem's preferred size the // the background image public Dimension getPreferredSize() { return new Dimension( backgroundImage.getIconWidth(), backgroundImage.getIconHeight() ); }
65
66 67 68 69 70 71 72 73 74 75 76 }
Draw city name, high/low, and attach weather image to width and height of WeatherItem.
Compile and Execute the Server and the Client Build and execute application
All pieces in place Compile classes with javac Remote server class (TemperatureServerImpl) compiled with rmic compiler
Makes a stub class - allows client to access remote methods and server to provide its services Gets remote method calls, passes to RMI system, which performs networking rmic TemperatureServerImpl
Compile and Execute the Server and the Client Start rmiregistry
Type rmiregistry at command window
No text in response
Compile and Execute the Server and the Client Must bind remote server object
Run TemperatureServerImpl application java TemperatureServerImpl Superclass UnicastRemoteObject
Constructor exports remote object main binds object to rmiregistry rmiregistry provides host and port number to clients
Compile and Execute the Server and the Client Execute TemperatureClient
java TemperatureClient If server on different machine, specify IP on command line java TemperatureClient 192.168.150.4 Result on next slide
Program Output