dot.NET.Framework.Essentials.1002003,.3Ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

dot.NET.Framework.Essentials.1002003,.3Ed [Electronic resources] - نسخه متنی

Hoang Lam; Thuan L. Thai

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










4.2 Distributed Components


A
component
technology should support distributed computing, allowing you to
activate and invoke remote services, as well as services in another
application domain.[5]
Distributed COM, or DCOM, is the wire
protocol that provides support for distributed computing using COM.
Although DCOM is fine for distributed computing, it is inappropriate
for global cyberspace because it doesn't work well
in the face of firewalls and NAT software. Some
other shortcomings of DCOM are expensive lifecycle management,
protocol negotiation, and binary formats.

[5] Each Windows process requires its
own memory address space, making it fairly expensive to run multiple
Windows processes. An application domain is a lightweight or virtual
process. All application domains of a given Windows process can use
the same memory address space.


To eliminate or at least mitigate these shortcomings, .NET provides a
host of different distributed support. The Remoting API in .NET
allows you to use a host of channels, such as TCP and HTTP (which
uses SOAP by default), for distributed computing. It even permits you
to plug in your own custom channels, should you require this
functionality. Best of all, since the framework is totally
object-oriented, distributed computing in .NET
couldn't be easier. To show you how simple it is to
write a distributed application in .NET, let's look
at an example using sockets, otherwise known as the TCP
channel in .NET.


4.2.1 Distributed Hello Server


In
this example,
we'll write a distributed Hello application, which
outputs a line of text to the console whenever a client invokes its
exposed method, SayHello( ). Since we're using the
TCP channel, we'll tell the compiler that we need
the definitions in the System.Runtime.Remoting and
System.Runtime.Remoting.Channels.Tcp
namespaces.

Note that this class, CoHello, derives from
MarshalByRefObject.[6]

[6] If you
fail to do this, your object will not have a distributed identity
since the default is marshal-by-value, which means that a copy of the
remote object is created on the client side.


This
is the key to distributed computing in .NET because it gives this
object a distributed identity, allowing the object to be referenced
across application domains, or even process and machine boundaries. A
marshal-by-reference
object
requires a proxy to be set up on the client side and a stub to be set
up on the server side, but since both of these are automatically
provided by the infrastructure, you don't have to do
any extra work. Your job is to derive from MarshalByRefObject to get
all the support for distributed computing:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
public class CoHello : MarshalByRefObject
{
public static void Main( )
{
TcpChannel channel = new TcpChannel(4000);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType (
typeof(CoHello), // Type name
"HelloDotNet", // URI
WellKnownObjectMode.Singleton // SingleCall or Singleton
);
System.Console.WriteLine("Hit <enter> to exit . . . ");
System.Console.ReadLine( );
}
public void SayHello( )
{
Console.WriteLine("Hello, Universe of .NET");
}
}

The SayHello( ) method is public, meaning that any external client
can call this method. As you can see, this method is very simple, but
the interesting thing is that a remote client application (which
we'll develop shortly) can call it because the Main(
) function uses the TcpChannel class. Look carefully at Main( ), and
you'll see that it instantiates a TcpChannel,
passing in a port number from which the server will listen for
incoming requests.[7]

[7] Believe it or not, all you really
have to do is replace TcpChannel with HttpChannel to take advantage
of HTTP and SOAP as the underlying communication protocols.


Once we have created a channel object, we then register the channel
to the ChannelServices, which supports channel registration and
object resolution. Having done this, you must then register your
object with the RemotingConfiguration so that it can be
activatedyou do this by calling the
RegisterWellKnownServiceType( ) method of
the RemotingConfiguration class. When you call this method, you must
pass in the class name, a URI, and an object-activation mode. The URI
is important because it's a key element that the
client application will use to refer specifically to this registered
object. The object-activation mode can be either Singleton, which
means that the same object will service many calls, or SingleCall,
which means an object will service at most one call.

Here's how to build this distributed application:

csc server.cs

Once you've done this, you can start the server
program, which will wait endlessly until you hit the Enter key. The
server is now ready to service client requests.


4.2.2 Remote Hello Client


Now that we have a server waiting, let's develop a
client to invoke the remote SayHello( ) method. Instead of
registering an object with the remoting configuration, we need to
activate a remote object. So let's jump into the
code now to see how this works. As you examine the following program,
note these items:

We're using types in the
System.Runtime.Remoting and
System.Runtime.Remoting.Channels.Tcp
namespaces, since we want to use the TCP channel.

Our Client class doesn't need to derive from
anything because it's not a server-side object that
needs to have a distributed identity.

Since we're developing a client application, we
don't need to specify a client port when we
instantiate the TcpChannel.


Other than these items, the key thing to note is object activation,
shown in the second boldface statement in the following code. To
invoke remote methods, you must first activate the remote object and
obtain an associated proxy on the client side. To activate the object
and get a reference to the associated proxy, you call the
GetObject( ) method of the
Activator class. When you do this, you
must pass along the remote class name and its fully qualified
location, including the complete URI. Once you've
successfully done this, you can then invoke remote methods.

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
public class Client
{
public static void Main( )
{
try
{
TcpChannel channel = new TcpChannel( );
ChannelServices.RegisterChannel(channel);
CoHello h = (CoHello) Activator.GetObject(
typeof(CoHello), // Remote type
"tcp://127.0.0.1:4000/HelloDotNet" // Location
);
h.SayHello( );
}
catch(Exception e)
{
Console.WriteLine(e.ToString( ));
}
}
}

To build this client application, you must include references to the
server.exe assembly:

csc /r:Server.exe Client.cs

If you're familiar with DCOM, you must be relieved
to find that it's relatively simple to write
distributed applications in .NET.[8]

[8] In fact, if you
have a copy of Learning DCOM
(O'Reilly) handy, compare these programs with their
DCOM counterparts in Appendix D, and you will see what we
mean.



4.2.3 Distributed Garbage Collector


Because the
.NET distributed garbage collector is different from that of DCOM, we
must briefly cover this facility. Instead of using
DCOM's delta pinging, which requires few network
packets when compared to normal pinging (but still too many for a
distributed protocol), .NET remoting uses leases to manage object
lifetimes. If you've ever renewed the lease to an IP
address on your Dynamic Host Configuration Protocol
(DHCP) network, you've pretty much figured out this
mechanism because it's based on similar concepts.

In .NET, distributed objects give out leases instead of relying on
reference counting (as in COM) for lifetime management. An
application domain where the remote objects reside has a special
object called the lease manager,
which manages all the leases associated with these remote objects.
When a lease expires, the lease manager contacts a sponsor, telling
the sponsor that the lease has expired. A
sponsor
is simply a client that has previously registered itself with the
lease manager during an activation call, indicating to the lease
manager that it wants to know when a lease expires. If the lease
manager can contact the sponsor, the sponsor may then renew the
lease. If the sponsor refuses to renew the lease or if the lease
manager can't contact the sponsor after a
configurable timeout period, the lease manager will void the lease
and remove the object. There are two other ways in which a lease can
be renewed: implicitly, via each call to the remote object, or
explicitly, by calling the Renew( ) method of
the ILease interface.


/ 121