Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 46

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 most-
significant (big-endian), least-significant(little-
endian)
Execution of RPC
Remote Method Invocation

• Remote Method Invocation (RMI) is a Java mechanism


similar to RPCs.
• RMI allows a Java program on one machine to invoke a
method on a remote object.
Marshalling Parameters
Remote Method Invocation

• RMI and RPC differs in two ways:


1. RPCs support procedural programming whereby only
remote procedures or functions may be called. RMI is
object based: It supports invocation of methods on remote
objects.
2. The parameters to remote procedures are ordinary data
structures in RPC; with RMI it is possible to pass objects
as parameters to remote methods.

• If the marshaled parameters are local (non remote) objects,


they are passed by copy using a technique known as object
serialization.
– Object serialization allowed the state of an object to be
written toa byte stream.
Introduction to RMI

• Remote Method Invocation (RMI)


– Allows remote method calls
• Objects in different programs can communicate
• Method calls appear same as those in same program
– Based on Remote Procedure Calls (RPC)
• Developed in 1980's
• Allows procedural program (like C) to call function on another
computer
• Performs networking and marshalling of data (packaging
arguments and return values)
• Not compatible with objects
• Interface Definition Language required - describe functions
– RMI is Java's implementation of RPC
Introduction to RMI

• RMI
– Register method as remotely accessible
• Client can look up method and receive a reference
• Use reference to call method
• Syntax same as a normal method call
– Marshalling of data
• Can transfer objects as well
• Class ObjectOutputStream converts Serializable
object into stream of bytes
– Transmit across network
• Class ObjectInputStream reconstructs object
– No Interface Definition Language needed
• Use Java's own interface
Case Study: Creating a Distributed System with
RMI
• RMI example
– Downloads weather information from National Weather
Service website
http://iwin.nws.noaa.gov/iwin/us/traveler.html
• Note: Format of website changed several times, if example does
not work do the appropriate modifications.
– Store information on a server
• Request information through remote method calls
Case Study: Creating a Distributed System
with RMI
Case Study: Creating a Distributed System with
RMI
• Four major steps
– Define remote interface
• Describes client/server communication
– Define server application to implement remote interface
• Same name as remote interface, ends with Impl
– Define client application that uses remote interface reference
• Interacts with server implementation
– Compile and execute server and client
Defining the Remote Interface
• First step
– Define remote interface that describes remote methods
• Client calls remote methods, server implements them
• To create a remote interface
– Define interface that extends interface Remote
(java.rmi)
• Tagging interface - no methods to define
• An object of a class that implements interface Remote directly
or indirectly is a remote object and can be accesses from any
JVM.
– Each method in Remote interface must throw
RemoteException
• Potential network errors
Defining the Remote Interface

• Interface TemperatureServer
– Extends Remote
– Describes method getWeatherInfo
1// Fig. 20.1: TemperatureServer.java
2// TemperatureServer interface definition

3 import java.rmi.*; Interface Remote in java.rmi


4

5public interface TemperatureServer extends Remote { 1. import


6 public WeatherInfo[] getWeatherInfo()

7 throws RemoteException; 1.1 extends Remote


8}

2. getWeatherInfo
Methods in Remote interface (is a relationship)
must be able to throw a RemoteException. 2.1 throws
RemoteException
Implementing the Remote Interface

• Define TemperatureServerImpl
– Implements Remote interface TemperatureServer
– Client interacts with TemperatureServerImpl object
– Uses array of WeatherInfo objects to store data
• Copy sent to client when calls getWeatherInfo
Implementing the Remote Interface
18 public class TemperatureServerImpl extends UnicastRemoteObject
19 implements TemperatureServer {

– 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

• Subclass constructors must throw RemoteExceptions

37 URL url = new URL(


38 "http://iwin.nws.noaa.gov/iwin/us/traveler.html" );

– URL object
• Contains URL for Traveler's Forecast web page
• Throws MalformedURLException
Implementing the Remote Interface
40 BufferedReader in =
41 new BufferedReader(
42 new InputStreamReader( url.openStream() ) );

– Open connection to file specified by URL


– Method openStream (class URL)
• Opens network connection using Http protocol
• If successful, InputStream object returned (else
IOException)
– InputStreamReader
• Translates bytes to Unicode characters
– BufferedReader
• Buffers characters
• Method readLine
– Returns one line as a String
Implementing the Remote Interface
44 String separator = "</PRE><HR> <BR><PRE>";
47 while ( !in.readLine().startsWith( separator ) )
48 ; // do nothing

– Sentinel String to find relevant part of HTML code


• readLine until sentinel found

51 String s1 =
52 "CITY WEA HI/LO WEA HI/LO";

– A string used as column head


• Second "WEA HI/LO" is for next day, we do not use
– Locate column head and get first city's info
66 inputLine = in.readLine(); // get first city's info
Implementing the Remote Interface
70 WeatherInfo w = new WeatherInfo(
71 inputLine.substring( 0, 16 ),
72 inputLine.substring( 16, 22 ),
73 inputLine.substring( 23, 29 ) );
75 cityVector.addElement( w ); // add to Vector

– WeatherInfo objects
• City name, temperature, description of weather
– Method substring to extract data from line
• Store all WeatherInfo objects in a Vector
84 weatherInformation[ i ] =
85 ( WeatherInfo ) cityVector.elementAt( i );

– Store data in WeatherInfo array


• elementAt returns Object (must be cast)
88 in.close(); // close connection to NWS server

– Close connection
Implementing the Remote Interface
116 String serverObjectName = "//localhost/TempServer";

– Name of server object


• Used by clients to connect
• //host:port/remoteObjectName
– host - computer running registry for remote objects
» Where remote object executes
– port - port number of registry on host (1099 default)
– remoteObjectName - client uses to locate object
– Registry managed by rmiregistry (located at host and
port)
• Remote objects register with it, clients use it to locate service
• localhost (same computer)
– Same as IP 127.0.0.1
Implementing the Remote Interface
112 TemperatureServerImpl temp =
113 new TemperatureServerImpl();

116 String serverObjectName = "//localhost/TempServer";


117 Naming.rebind( serverObjectName, temp );

– static method rebind (class Naming)


• Binds object to rmiregistry
• Named //localhost/TempServer
– Name used by client
• rebind replaces any previous objects with same name
– Method bind does not
1// Fig. 20.1: TemperatureServer.java
2// TemperatureServer interface definition

3import java.rmi.*;

4
1. Interface
5public interface TemperatureServer extends Remote { ------------------
6 public WeatherInfo[] getWeatherInfo()
7 throws RemoteException;
1. extends
8}
UnicastRemote
9TemperatureServer interface.
Object, implements
10 // Fig. 20.2: TemperatureServerImpl.java
TemperatureServer
11 // TemperatureServerImpl definition
12 import java.rmi.*;
13 import java.rmi.server.*; 1.1 Constructor
14 import java.util.*;
Allows objects to be exported.
15 import java.io.*;

16 import java.net.*;

17

18 public class TemperatureServerImpl extends UnicastRemoteObject


19 implements TemperatureServer {

20 private WeatherInfo weatherInformation[];


21

22 public TemperatureServerImpl() throws RemoteException


23 {
24 super();
25 updateWeatherConditions(); Superclass constructor exports objects, and
26 } this constructor must be able to throw
27 RemoteException.
28 // get weather information from NWS
29 private void updateWeatherConditions()
30 throws RemoteException
31 {
32 try { 2. updateWeather
33 System.err.println( URL of web site (URL object). Conditions
34 "Updating weather information..." );

35

36 // Traveler's Forecast Web Page


2.1 URL
37 URL url = new URL(
38 "http://iwin.nws.noaa.gov/iwin/us/traveler.html" );
2.2 BufferedReader
39

40 BufferedReader in =
41 new BufferedReader( 2.3 readLine
42 new InputStreamReader( url.openStream() ) );

43

44 String separator = "</PRE><HR> <BR><PRE>";

45

46 // locate first horizontal line on Web page Open connection to file.


47 while ( !in.readLine().startsWith( InputStreamReader
separator ) ) formats it to Unicode
48 ; // do nothing
characters, and BufferedReader buffers the
49

50 // s1 is the day format and s2 is the night format


characters.
51 String s1 =

52 "CITY WEA HI/LO WEA HI/LO";


readLine until separator found.
53 String s2 =

54 "CITY WEA LO/HI WEA LO/HI";

55 String inputLine = "";

56
57 // locate header that begins weather information

58 do {

59 inputLine = in.readLine();

60 } while ( !inputLine.equals( s1 ) &&

61 !inputLine.equals( s2 ) ); Create WeatherInfo object, add data


2.4 Locate header
62 (substring), add to Vector. Loop until
63 blank line reached.
64 Vector cityVector = new Vector();
2.5 Loop
65

66 inputLine = in.readLine(); // get first city's info

67 2.5.1 WeatherInfo
68 while ( !inputLine.equals( "" ) ) {
69 // create WeatherInfo object for city

70 WeatherInfo w = new WeatherInfo( 2.5.2 readLine


71 inputLine.substring( 0, 16 ),

72 inputLine.substring( 16, 22 ),
2.6 WeatherInfo array
73 inputLine.substring( 23, 29 ) );

74

75 cityVector.addElement( w ); // add to Vector

76 inputLine = in.readLine(); // get next city's info

77 }

78
Create WeatherInfo array, cast
79 // create array to return to client
Vector elements.
80 weatherInformation =
81 new WeatherInfo[ cityVector.size() ];

82

83 for ( int i = 0; i < weatherInformation.length; i++ )

84 weatherInformation[ i ] =

85 ( WeatherInfo ) cityVector.elementAt( i );

86
87 System.err.println( "Finished Processing Data." );

88 in.close(); // close connection to NWS server

89 }

90 catch( java.net.ConnectException ce ) {

91 System.err.println( "Connection failed." ); 2.7 close


92 System.exit( 1 );

93 }
94 catch( Exception e ) {
3. getWeatherInfo
95 e.printStackTrace();

96 System.exit( 1 ); 4. main
97 }

98 } Return the WeatherInfo array.


99
4.1 temp
100 // implementation for TemperatureServer interface method

101 public WeatherInfo[] getWeatherInfo()


102 {

103 return weatherInformation;


104 }
105

106 public static void main( String args[] ) throws Exception

107 {

108 System.err.println(

109 "Initializing server: please wait." );


110

111 // create server object

112 TemperatureServerImpl temp =

113 new TemperatureServerImpl();

114
115 // bind TemperatureServerImpl object to the rmiregistry
116 String serverObjectName = "//localhost/TempServer";
117 Naming.rebind( serverObjectName, temp );
118 System.err.println( 4.2
119 "The Temperature Server is up and running." ); server object. serverObjectName
Name of
120 }
121 } 4.3 rebind
rebind binds object to
rmiregistry.
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 1. Class WeatherInfo
6 public class WeatherInfo implements Serializable { implements
7 private String cityName;
Serializable
8 private String temperature;

9 private String description;

10 1. Instance variables
11 public WeatherInfo( String city, String desc, String temp )

12 {
1.1 Constructor
13 cityName = city;

14 temperature = temp;

15 description = desc; 2. Get methods


16 }

17

18 public String getCityName() { return cityName; }

19

20 public String getTemperature() { return temperature; }

21

22 public String getDescription() { return description; }

23 }
Define the client

• Next step
– Client code to get weather info from
TemperatureServerImpl
– Calls getWeatherInfo through RMI
– Graphically display weather info
• Class WeatherItem (extends JLabel) stores info about
each city
• Display name, High/low, and image (depending on conditions)
Define the client
22 private void getRemoteTemp( String ip )
26 String serverObjectName = "//" + ip + "/TempServer";

– Can specify IP address at command line (more later)


30 TemperatureServer mytemp = ( TemperatureServer )
31 Naming.lookup( serverObjectName );

– static method lookup (class Naming)


– Returns reference to Remote object
• Cast to TemperatureServer
– Reference may be used as normal
• Only difference that copy of array returned
34 WeatherInfo weatherInfo[] = mytemp.getWeatherInfo();
Define the client
40 JPanel p = new JPanel();
50 for ( int i = 0; i < w.length; i++ ) {
51 w[ i ] = new WeatherItem( weatherInfo[ i ] );

52 p.add( w[ i ] );
53 }

– Add WeatherItems
• Initialize with WeatherInfo
68 public static void main( String args[] )
69 {
70 TemperatureClient gt = null;
74 if ( args.length == 0 )
75 gt = new TemperatureClient( "localhost" );
76 else
77 gt = new TemperatureClient( args[ 0 ] );

– main
• Passes command line argument (ip) to constructor
• localhost default
Define the client

• Class WeatherItem
– extends JLabel
– static initializer block
• For complex initialization of static variables
• backgroundImage - ImageIcon, has background
• weatherImages - ImageIcon array, holds 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 }
Define the client

– Array of descriptions and matching array of images


• weatherConditions and weatherImages
32 public WeatherItem( WeatherInfo w )
35 weatherInfo = w;
38 for ( int i = 0; i < weatherConditions.length; ++i )

39 if ( weatherConditions[ i ].equals(
40 weatherInfo.getDescription().trim() ) ) {

41 weather = weatherImages[ i ];

– Tests WeatherInfo object, loads proper image


1// Fig. 20.4: TemperatureClient.java

2// TemperatureClient definition

3import java.awt.*;

4import java.awt.event.*;

5import javax.swing.*;

6import java.rmi.*;
1. import
7

8public class TemperatureClient extends JFrame


1.1 Constructor
9{

10 public TemperatureClient( String ip )

11 { 2. getRemoteTemp
12 super( "RMI TemperatureClient..." );

13 getRemoteTemp( ip );

14 2.1
15 setSize( 625, 567 );
serverObjectName
16 setResizable( false );

17 show(); Use ip specified at command line.


18 } 2.2 Naming.lookup
19

20 // obtain weather information from TemperatureServerImpl Lookup remote object in


21 // remote object registry. Returns Remote
22 private void getRemoteTemp( String ip )
reference, cast to proper type.
23 {

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 // get weather information from server
34 WeatherInfo weatherInfo[] = mytemp.getWeatherInfo();

35 WeatherItem w[] =

Call2.3
likegetWeatherInfo
36 new WeatherItem[ weatherInfo.length ];
regular method.
37 ImageIcon headerImage =

38 new ImageIcon( "images/header.jpg" );

39 2.4 GUI
40 JPanel p = new JPanel();

41

42 // determine number of rows for the GridLayout; 2.4.1 WeatherItem


43 // add 3 to accommodate the two header JLabels

44 // and balance the columns

45 p.setLayout(

46 new GridLayout( ( w.length + 3 ) / 2, 2 ) );

47 p.add( new JLabel( headerImage ) ); // header 1

48 p.add( new JLabel( headerImage ) ); // header 2

49

50 for ( int i = 0; i < w.length; i++ ) {

51 w[ i ] = new WeatherItem( weatherInfo[ i ] );

52 p.add( w[ i ] );

53 }

54

55 getContentPane().add( new JScrollPane( p ),

56 BorderLayout.CENTER );

57 }

58 catch ( java.rmi.ConnectException ce ) {

59 System.err.println( "Connection to server failed. " +

60 "Server may be temporarily unavailable." );

61 }
62 catch ( Exception e ) {
63 e.printStackTrace();
64 System.exit( 1 );
65 }
66 } 3. main
67
68 public static void main( String args[] )
3.1 args[ 0 ]
69 {
70 TemperatureClient gt = null;
71
72 // if no sever IP address or host name specified,
73 // use "localhost"; otherwise use specified host

74 if ( args.length == 0 )
75 gt = new TemperatureClient( "localhost" );
76 else args[ 0 ] is the first
77 gt = new TemperatureClient( args[ 0 ] ); argument, which should be
78 the IP address.
79 gt.addWindowListener(

80 new WindowAdapter() {
81 public void windowClosing( WindowEvent e )
82 {

83 System.exit( 0 );
84 }

85 }
86 );
87 }

88 }
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;

8 private final static String weatherConditions[] = 1.1 static variables


9 { "SUNNY", "PTCLDY", "CLOUDY", "MOCLDY", "TSTRMS",

10 "RAIN", "SNOW", "VRYHOT", "FAIR", "RNSNOW",

11 "SHWRS", "WINDY", "NOINFO", "MISG" }; 1.2 Initializer block


12 private final static String weatherImageNames[] =

13 { "sunny", "pcloudy", "mcloudy", "mcloudy", "rain",

14 "rain", "snow", "vryhot", "fair", "rnsnow",


1.3 Load ImageIcons
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 public WeatherItem( WeatherInfo w )

33 {

34 weather = null;

35 weatherInfo = w; 2. Constructor
36

37 // locate image for city's weather condition

38 for ( int i = 0; i < weatherConditions.length; ++i ) 2.1 Compare conditions


39 if ( weatherConditions[ i ].equals(

40 weatherInfo.getDescription().trim() ) ) { 3. paintComponent
41 weather = weatherImages[ i ];

42 break;

43 } Loop though weatherConditions


3.1 paintIcon and
44 compare to getDescription.
45 // pick the "no info" image if either there is no

46 // weather info or no image for the current

47 // weather condition

48 if ( weather == null ) {

49 weather = weatherImages[ weatherImages.length - 1 ];

50 System.err.println( "No info for: " +

51 weatherInfo.getDescription() );

52 }

53 }

54

55 public void paintComponent( Graphics g ) Attach background to WeatherItem.


56 {

57 super.paintComponent( g );

58 backgroundImage.paintIcon( this, g, 0, 0 );
59
60 Font f = new Font( "SansSerif", Font.BOLD, 12 );
61 g.setFont( f );
62 g.setColor( Color.white );
63 g.drawString( weatherInfo.getCityName(), 10, 19 );
3.2 drawString
64 g.drawString( weatherInfo.getTemperature(), 130, 19 );
65
3.3 paintIcon
66 weather.paintIcon( this, g, 253, 1 );
67 }
68 Draw city name, high/low, and attach
69 // make WeatherItem's preferred size the width weather
and heightimage
of to WeatherItem.
70 // the background image
71 public Dimension getPreferredSize()
72 {
73 return new Dimension( backgroundImage.getIconWidth(),
74 backgroundImage.getIconHeight() );
75 }
76 }
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

You might also like