View
216
Download
2
Tags:
Embed Size (px)
Citation preview
Carnegie Mellon University MSCF
1
.NET Distributed Computing
Notes from “Distributed .NET Programming in C#” byTom Barnaby and“.NET Programming” by Pradeep Tapadiya
Carnegie Mellon University MSCF
2
Remote Objects
• We can’t call methods on remote objects directly. We call methods on remote objects through a remote reference to that object.
• Parameters to and from the remote method are “marshaled”
Carnegie Mellon University MSCF
3
Marshaling Classification
• Marshal-by-value
• Marshal-by-reference
• Nonremotable
Carnegie Mellon University MSCF
4
Marshal-By-Value Objects
• Objects marked with the custom attribute [serializable] are pass-by-value objects
• The entire object is copied into the remote domain
• Any local change to the object is not reflected in the remote domain
Carnegie Mellon University MSCF
5
Marshal-By-Reference Object
• MBR objects derive from MarshalByRefObject
• The client of such an object is actually making calls on a proxy object created by the runtime
Carnegie Mellon University MSCF
6
MBR Objects (1)using System;using System.Threading;
public class Foo : MarshalByRefObject {
public void DisplayDomainInfo() {
String s = "Domain=" + AppDomain.CurrentDomain.FriendlyName + " Thread ID=" + AppDomain.GetCurrentThreadId() + " Context ID=" + Thread.CurrentContext.ContextID; Console.WriteLine(s); }}
Carnegie Mellon University MSCF
7
public class MyApp {
public static void Main() {
Foo fDefault = new Foo(); // No proxy is used because we are fDefault.DisplayDomainInfo(); // not crossing domains
}}
D:\..\46-690\MBRandMBV>mbvandmbr.exe
Domain=mbvandmbr.exe Thread ID=2284 Context ID=0
Carnegie Mellon University MSCF
8
MBR Objects (2)public class MyApp {
public static void Main() {
Foo fDefault = new Foo(); fDefault.DisplayDomainInfo(); // force a call by remote reference // fNew points to a proxy AppDomain ad = AppDomain.CreateDomain("MyNewAppDomain"); Foo fNew = (Foo) ad.CreateInstanceAndUnwrap("mbvandmbr", "Foo"); fNew.DisplayDomainInfo(); }}
D:\..\46-690\MBRandMBV>mbvandmbrDomain=mbvandmbr.exe Thread ID=2096 Context ID=0Domain=MyNewAppDomain Thread ID=2096 Context ID=0
Carnegie Mellon University MSCF
9
MBR Objects (3)using System;using System.Threading;
[Serializable] // make Serializable and remove MarshalByReferencepublic class Foo {
public void DisplayDomainInfo() {
String s = "Domain=" + AppDomain.CurrentDomain.FriendlyName + " Thread ID=" + AppDomain.GetCurrentThreadId() + " Context ID=" + Thread.CurrentContext.ContextID; Console.WriteLine(s); }}
Carnegie Mellon University MSCF
10
public class MyApp {
public static void Main() {
Foo fDefault = new Foo(); fDefault.DisplayDomainInfo();
AppDomain ad = AppDomain.CreateDomain("MyNewAppDomain"); Foo fNew = (Foo) ad.CreateInstanceAndUnwrap("mbvandmbr", "Foo"); fNew.DisplayDomainInfo(); }}
D:\...\46-690\MBRandMBV>mbvandmbrDomain=mbvandmbr.exe Thread ID=588 Context ID=0Domain=mbvandmbr.exe Thread ID=588 Context ID=0
Carnegie Mellon University MSCF
11
Remoting Model
REMOTING
LAYER
REMOTING
LAYER
Client Object Server Object
Proxy Channel
Namespaces:System.Runtime.Remoting.Channels.Tcp binary serializationSystem.Runtime.Remoting.Channels.Http uses Microsoft SOAP serializationClasses:TcpServerChannel, HttpServerChannel, TcpClientChannel, HttpClientChannel
Carnegie Mellon University MSCF
12
Remote Objects May Be
• Server-Activated Objects
(The server controls the lifetime)
• Client-Activated Objects
(The client controls the lifetime)
Carnegie Mellon University MSCF
13
Server Activated Objects Server activated objects – with a well-known name assigned on the server
The server code -- Registers a server side channel -- Registers the name of the remote object -- Provides a mechanism to keep the server alive -- Creates the object on the first call to the object trough the client side proxy The Client code -- Registers a client side channel -- Create a proxy with Activator.GetObject passing a type and a location -- Make calls on the proxy as though they were calls on the remote object
Carnegie Mellon University MSCF
14
Single-Call and Singletons
• Server Activated objects are published as either single-call or singleton objects
• Single-call => on each call from the client the object is created and then torn down
(WellKnownObjectMode.SingleCall)• Singleton => only one object exists and is
shared by callers (no synchronization)
(WellKnownObjectMode.Singleton)• Neither of these is appropriate for holding state
Carnegie Mellon University MSCF
15
Client Activated Objects
• The client requests that an instance be created on the server
• For each instance requested a proxy is returned to the client
• The client may store instance specific state in the object (through the proxy)
• The objects are garbage collected when their leases expire
Carnegie Mellon University MSCF
16
The Object To Be Served// A Remote Student Objectusing System;
public class RemoteStudent : MarshalByRefObject {
private int age; private String name;
public int getAge() { return age; } public String getName() { return name; }
public void setAge(int age) { this.age = age; } public void setName(string name) { this.name = name; } }
Carnegie Mellon University MSCF
17
Client Code (along with Student.dll)using System.Runtime.Remoting.Channels.Tcp;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting;using System;using System.Runtime.Remoting.Activation;
class MyClient {
public static void Main() { ChannelServices.RegisterChannel(new TcpClientChannel());
RemoteStudent r = (RemoteStudent) Activator.CreateInstance( typeof(RemoteStudent),null, new object[] { new UrlAttribute( "tcp://localhost:6502") } );
Carnegie Mellon University MSCF
18
r.setName("Bob"); r.setAge(23); RemoteStudent s = (RemoteStudent) Activator.CreateInstance( typeof(RemoteStudent),null, new object[] { new UrlAttribute( "tcp://localhost:6502") } );
s.setName("Alice"); s.setAge(22);
Console.WriteLine("Name: " + s.getName() + " age " + s.getAge()); Console.WriteLine("Name: " + r.getName() + " age " + r.getAge()); }
}
Carnegie Mellon University MSCF
19
Server Code (with Student.dll)using System.Runtime.Remoting.Channels.Tcp;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting;using System;
class MyApp {
public static void Main() {
ChannelServices.RegisterChannel( new TcpServerChannel(6502)); RemotingConfiguration.RegisterActivatedServiceType( Type.GetType("RemoteStudent, Student")); Console.WriteLine("Press a key to exit server"); Console.Read(); }}
Carnegie Mellon University MSCF
20
Output
..46-690\RemoteObjects3\client>MyClient
Name: Alice age 22
Name: Bob age 23
Carnegie Mellon University MSCF
21
Leases
• .NET uses a lease to manage the lifetime of remote (client activated) objects.
• A lease may be extended by the client
• When the lease expires the object is garbage collected and subsequent calls on the proxy will generate a RemotingException
Carnegie Mellon University MSCF
22
using System.Runtime.Remoting.Channels.Tcp;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting;using System;using System.Runtime.Remoting.Activation;using System.Threading;
The Client Side Lets a Lease Expire
Carnegie Mellon University MSCF
23
class MyClient {
public static void Main() {
try { ChannelServices.RegisterChannel(new TcpClientChannel());
RemoteStudent r = (RemoteStudent) Activator.CreateInstance( typeof(RemoteStudent),null, new object[] { new UrlAttribute( "tcp://localhost:6502") } );
Carnegie Mellon University MSCF
24
r.setName("Bob"); r.setAge(23);
Thread.Sleep(45000); // wait 45 seconds after creating Bob RemoteStudent s = (RemoteStudent) Activator.CreateInstance( typeof(RemoteStudent),null, new object[] { new UrlAttribute( "tcp://localhost:6502") } ); s.setName("Alice"); s.setAge(22); Console.WriteLine("Name: " + s.getName() + " age " + s.getAge()); Console.WriteLine("Name: " + r.getName() + " age " + r.getAge()); } catch(RemotingException e) { Console.WriteLine("Caught exception " + e); // Bob causes trouble } }}
Carnegie Mellon University MSCF
25
A Student With A Lease// A Remote Student Objectusing System;using System.Runtime.Remoting.Lifetime;
public class RemoteStudent : MarshalByRefObject {
private int age; private String name;
public int getAge() { return age; } public String getName() { return name; }
public void setAge(int age) { this.age = age; } public void setName(string name) { this.name = name; }
Carnegie Mellon University MSCF
26
public override Object InitializeLifetimeService() {
Console.WriteLine("Lease code called"); // whenever called call base class method ILease lease = (ILease) base.InitializeLifetimeService();
// if first call make some changes if (lease.CurrentState == LeaseState.Initial) { lease.InitialLeaseTime = TimeSpan.FromSeconds(30); lease.RenewOnCallTime = TimeSpan.FromSeconds(10); } return lease; }}
Carnegie Mellon University MSCF
27
Same Server Codeusing System.Runtime.Remoting.Channels.Tcp;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting;using System;
class MyApp {
public static void Main() {
ChannelServices.RegisterChannel( new TcpServerChannel(6502)); RemotingConfiguration.RegisterActivatedServiceType( Type.GetType("RemoteStudent, Student"));
Console.WriteLine("Press a key to exit server"); Console.Read(); }}
Carnegie Mellon University MSCF
28
..\46-690\RemoteObjects3\client>MyClientName: Alice age 22Caught exception System.Runtime.Remoting.RemotingException: No receiver registered
D:..\46-690\RemoteObjects3\server>ServerPress a key to exit serverLease code calledLease code called
Output
Carnegie Mellon University MSCF
29
The soapsuds tool
• Perhaps we do not want the client to have access to the Student code
• We only want the client to have access to meta information
• The soapsuds tool allows to download and then use meta information
Carnegie Mellon University MSCF
30
The server codeusing System.Runtime.Remoting.Channels.Http;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting;using System;
class MyApp {
public static void Main() {
ChannelServices.RegisterChannel( new HttpServerChannel(6502));
Carnegie Mellon University MSCF
31
RemotingConfiguration.RegisterWellKnownServiceType( Type.GetType("RemoteStudent, Student"), "SomeStudent/Student.soap", WellKnownObjectMode.SingleCall);
Console.WriteLine("Press a key to exit server"); Console.Read(); }}
// Compile the server code// csc -t:library Student.cs// csc -r:Student.dll Server.cs
Carnegie Mellon University MSCF
32
The Client Codeusing System.Runtime.Remoting.Channels.Http;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting;using System;
class MyClient {
public static void Main() {
ChannelServices.RegisterChannel(new HttpClientChannel());
RemoteStudent r = (RemoteStudent) Activator.GetObject( typeof(RemoteStudent), "http://localhost:6502/SomeStudent/Student.SOAP");
Carnegie Mellon University MSCF
33
String name = r.getName(); int age = r.getAge();
Console.WriteLine("Student Name: " + name + " Age: " + age); }
}
Carnegie Mellon University MSCF
34
Run The ClientBut this time we do not have the Student.dll available. So, MyClient.cscwill not compile.
1) Fetch the WSDL document from the server and generate the proxy class using soapsuds:
soapsuds -url:http://localhost:6502/SomeStudent/Student.soap?wsdl -oa:Student.dll
2) Compile and run the client: csc -r:Student.dll MyClient.cs MyClient Student Name: Mike Age: 23
Carnegie Mellon University MSCF
35
Web Services
“The internet is evolving from a collection of isolated web sites and applications into a general communication bus for distributed applications.”
From page 247 of the course text
Carnegie Mellon University MSCF
36
ASP.NET Web Services
0) Check if IIS is running by attempting to visit http://localhost
1) If it's not running click Start/Settings/Control
Panel/Add Remove Programs/
Add Remove Windows Components and
enable IIS.
2) If .NET was installed after IIS reconfigure IIS by running aspnet_regiis.exe /i from a command prompt.
Carnegie Mellon University MSCF
37
ASP.NET Web Services
Suppose we want to provide a student name
given a student ID
Carnegie Mellon University MSCF
38
ASP.NET Server Code <%@ WebService Language="C#" Class="Student.QueryService" %>
// CoolService.asmx
using System.Web.Services;using System.Collections;
namespace Student {
[WebService(Namespace="http://localhost/ACoolQueryService/")]
public class QueryService : WebService {
private static Hashtable nameValuePairs;
Carnegie Mellon University MSCF
39
static QueryService() {
nameValuePairs = new Hashtable(); nameValuePairs.Add("12345","Moe"); nameValuePairs.Add("01234","Curly Joe"); nameValuePairs.Add("54321","Larry"); }
[WebMethod] public string GetName(string id) { return (string)nameValuePairs[id]; } }}
// We can’t compile this code with csc.
Carnegie Mellon University MSCF
40
Create a virtual directory under IIS
• Start• Settings • Control Panel• Administrative Tools• Select Internet Information Services• Expand and select the default web site• Click Action/New/Virtual Directory• Provide a name (ACoolQueryService in this case) and
browse to the directory holding the .asmx file• Select everything but write
Carnegie Mellon University MSCF
41
Checking the service
• Visit the service with your browser• http://localhost/ACoolQueryService/CoolService.asmx
• HTML is generated that allows you to test the service via standard HTTP
Carnegie Mellon University MSCF
42
Testing With HTTP Get
Request
GET /ACoolQueryService/CoolService.asmx/GetName?id=string HTTP/1.1 Host: localhost HTTP/1.1 200 OK
Content-Type: text/xml;
charset=utf-8
Content-Length: length
Response
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://localhost/ACoolQueryService/">string</string>
Carnegie Mellon University MSCF
43
Testing with SOAP POST /ACoolQueryService/CoolService.asmx HTTP/1.1 Host:
localhost Content-Type: text/xml; charset=utf-8 Content-Length: length of document SOAPAction: "http://localhost/ACoolQueryService/GetName"
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
Carnegie Mellon University MSCF
44
<soap:Body> <GetName xmlns="http://localhost/ACoolQueryService/"> <id>string</id> </GetName> </soap:Body> </soap:Envelope>
Carnegie Mellon University MSCF
45
SOAP Response HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
Carnegie Mellon University MSCF
46
<soap:Body> <GetNameResponse xmlns= "http://localhost/ACoolQueryService/"> <GetNameResult>string</GetNameResult> </GetNameResponse> </soap:Body></soap:Envelope>
Carnegie Mellon University MSCF
47
WSDL Structure
message operation(message)
message operation(message)
message operation(message)
typetype
{interface
• Operation names (method names)• Message types (parameters and return values)• Interfaces (groups of methods) are called ports• location of service
Carnegie Mellon University MSCF
48
Examine the WSDL
<?xml version="1.0" encoding="utf-8"?><definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://localhost/ACoolQueryService/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://localhost/ACoolQueryService/" xmlns="http://schemas.xmlsoap.org/wsdl/">
Namespaces disambiguate.
Carnegie Mellon University MSCF
49
<types>
<s:schema elementFormDefault="qualified" targetNamespace="http://localhost/ACoolQueryService/"> <s:element name="GetName"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="id" type="s:string" /> </s:sequence> </s:complexType> </s:element>
message type
<GetName>
<id> string</id>
</GetName
Carnegie Mellon University MSCF
50
<s:element name="GetNameResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1“ name="GetNameResult" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="string" nillable="true" type="s:string" /> </s:schema> </types> Message type
<GetNameResponse> <GetNameResult>string</GetNameResult> </GetNameResponse>
Message type <string>string</string>
Carnegie Mellon University MSCF
51
<message name="GetNameSoapIn"> <part name="parameters" element="s0:GetName" /> </message> <message name="GetNameSoapOut"> <part name="parameters" element="s0:GetNameResponse" /> </message> <message name="GetNameHttpGetIn"> <part name="id" type="s:string" /> </message>
Message GetNameSoapIn : GetNameMessage GetNameSoapOut : GetNameResponseMessage GetNameHttpGetIn: { id : string}
Carnegie Mellon University MSCF
52
<message name="GetNameHttpGetOut"> <part name="Body" element="s0:string" /> </message> <message name="GetNameHttpPostIn"> <part name="id" type="s:string" /> </message> <message name="GetNameHttpPostOut"> <part name="Body" element="s0:string" /> </message>
Message GetNameHttpGetOut: { body : s0:string}Message GetNameHttpPostIn: { id : string}Message GetNameHttpPostOut: { body: s0string}
Carnegie Mellon University MSCF
53
<portType name="QueryServiceSoap"> <operation name="GetName"> <input message="s0:GetNameSoapIn" /> <output message="s0:GetNameSoapOut" /> </operation> </portType>
<portType name="QueryServiceHttpGet"> <operation name="GetName"> <input message="s0:GetNameHttpGetIn" /> <output message="s0:GetNameHttpGetOut" /> </operation> </portType>
Interface QueryServiceSoap So:GetNameSoapOut GetName(s0:GetNameSoapIn)Interface QueryServiceHttpGet S0:GetNameHttpGetOut GetName(s0:GetNameHttpGetIn)
Carnegie Mellon University MSCF
54
<portType name="QueryServiceHttpPost"> <operation name="GetName"> <input message="s0:GetNameHttpPostIn" /> <output message="s0:GetNameHttpPostOut" /> </operation> </portType>
Carnegie Mellon University MSCF
55
<binding name="QueryServiceSoap" type="s0:QueryServiceSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="GetName"> <soap:operation soapAction="http://localhost/ACoolQueryService/GetName" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding>
Bind QueryServiceSOAP to the interface s0:QueryServiceSoapand describe how the data willlook on the wire
Carnegie Mellon University MSCF
56
<binding name="QueryServiceHttpGet" type="s0:QueryServiceHttpGet"> <http:binding verb="GET" /> <operation name="GetName"> <http:operation location="/GetName" /> <input> <http:urlEncoded /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding>
Carnegie Mellon University MSCF
57
<binding name="QueryServiceHttpPost" type="s0:QueryServiceHttpPost"> <http:binding verb="POST" /> <operation name="GetName"> <http:operation location="/GetName" /> <input> <mime:content type="application/x-www-form-urlencoded" /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding>
Carnegie Mellon University MSCF
58
<service name="QueryService"> <port name="QueryServiceSoap" binding="s0:QueryServiceSoap"> <soap:address location="http://localhost/ThreeStoogesTest/CoolService.asmx" /> </port> <port name="QueryServiceHttpGet" binding="s0:QueryServiceHttpGet"> <http:address location="http://localhost/ThreeStoogesTest/CoolService.asmx" /> </port> <port name="QueryServiceHttpPost" binding="s0:QueryServiceHttpPost"> <http:address location="http://localhost/ThreeStoogesTest/CoolService.asmx" /> </port> </service></definitions>
Provide addresses for each interface.
Carnegie Mellon University MSCF
59
Remoting Vs. Web Services
Characteristic .NET Remoting Web Services
Type system .NET Specific XML Schema
Client Platform .NET Any
Message Format
Binary, SOAP HTTP Post or Get Query strings or SOAP
Proxy building tool
Soapsuds.exe Wsdl.exe
Marshalling MBR or MBV MBV only
Interoperability No Yes