How To Choose: Rate This Topic
How To Choose: Rate This Topic
How To Choose: Rate This Topic
Overview
Over time, it has become common practice to build applications as a set of components that are distributed across a network of machines and work together as part of one overall program. Traditionally, distributed application logic called for component-object technology such as the Microsoft Distributed Component Object Model (DCOM), the Object Management Group's Common Object Request Broker Architecture (CORBA), or Sun's Remote Method Invocation (RMI). These technologies provided reliable, scalable architecture to meet the growing needs of applications. Though these component-based technologies work very well in an intranet environment, attempting to use them over the Internet presents two significant problems. First, the technologies do not interoperate. While they all dealt with objects, they disagreed over the details, for example, lifecycle management, support for constructors, and degree of support for inheritance. Second, and more important, their focus on RPC-style communication typically led to tightly coupled systems built around the explicit invocations of object methods. Browser-based Web applications, in contrast, are loosely coupled and remarkably interoperable. They communicate using HTTP to exchange MIME-typed data in a wide range of formats. Web services adapt the traditional Web programming model for use from all sorts of applications, not just browser-based ones. They exchange SOAP messages using HTTP and other Internet protocols. Because Web services rely on industry standards, including HTTP, XML, SOAP and WSDL, to expose application functionality on the Internet, they are independent of programming language, platform and device.
The ASP.NET Web services infrastructure provides a simple API for Web services based on mapping SOAP messages to method invocations. It accomplishes this by providing a very simple programming model based on mapping SOAP message exchanges to individual method invocations. The clients of ASP.NET Web services do not have to know anything about the platform, object model, or programming language used to build them. The services themselves don't have to know anything about the clients that are sending them messages. The only requirement is that both parties agree on the format of the SOAP messages being produced and consumed, as defined by the Web service's contract definition expressed using WSDL and XML Schema (XSD). .NET Remoting provides an infrastructure for distributed objects. It exposes the full-object semantics of .NET to remote processes using plumbing that is both very flexible and extensible. Compared to ASP.NET Web services, which provide a very simple programming model based on message passing, .NET Remoting offers much more complex functionality, including support for passing objects by value or by reference, callbacks, and multiple-object activation and lifecycle management policies. In order to use .NET Remoting, a client needs to be aware of all these details in short the client needs to be built using .NET. (Or with another framework that supports .NET Remoting; the only one we are aware of is Intrinsyc's Ja.NET for Java.) The .NET Remoting plumbing also supports SOAP messages, but it is important to note that this doesn't change its client requirements. If a Remoting endpoint exposes .NET-specific object semantics, via SOAP or not, the client must understand them. The fact that the .NET Framework includes support for two distinct distributed programming models, Web services and distributed objects, has caused a fair amount of confusion for developers. When should a system use ASP.NET Web services and when should it use .NET Remoting? To answer this question, you have to understand how both these technologies really work.
to describe its messages in terms of literal XSD or the SOAP encoding rules (i.e., SOAP Section 5). Literal XSD is the default, and will be the standard going forward. SOAP-encoding support is included for interoperability with existing toolkits. This is beneficial, especially when you need to communicate with an existing Web service or client that needs to communicate using a predefined message format.
If you generate WSDL from this class, the binding information includes .NET Remoting-specific details, as shown below.
<binding name='MethodsBinding' type='ns0:MethodsPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>
<suds:class type='ns0:Methods' rootType='MarshalByRefObject'> </suds:class> <operation name='Now'> <soap:operation soapAction= 'http://schemas.microsoft.com/clr/nsassem/RemSoap.Methods/methods#Now'/> <suds:method attributes='public'/> <input name='NowRequest'>...</input> <output name='NowResponse'>...</output> </operation> </binding>
These extra elements are legal because the WSDL specification supports extensibility. Any wellbehaved Web service toolkit that doesn't understand them should simply ignore them. However, there are some things a Web service toolkit cannot ignore. For instance, here is a Remoting endpoint that returns a Microsoft ADO.NET System.Data.DataSet.
public class Methods : MarshalByRefObject { public System.Data.DataSet GetEmptyDataSet() { return new System.Data.DataSet(); } }
Here is the generated WSDL definition for this method's output message:
<message name='Methods.GetEmptyDataSetOutput'> <part name='return' type='ns3:DataSet'/> </message>
Normally, a WSDL message refers to types defined in a particular namespace using XML Schema. In this case, however, the namespace prefix ns3 applied to the DataSet type is not defined in XSD. Instead it is implicitly defined via the runtime. The ns3 prefix in this example is bound to an XML namespace identified by this URI: http://schemas.microsoft.com/clr/nsassem/System.Data/System.Data%2C%20Version %3D1.0.3300.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db77a5c561934e089 Consumers of this WSDL definition are meant to understand the special significance of this "wellknown" URIit is the four-part strong name of a specific runtime assembly included in the .NET Framework. This style of WSDL is great for clients that are implemented using .NET Remoting because they can generate a proxy assembly with the right information for marshaling. However, for other Web service toolkitsincluding ASP.NETthat do not understand this URI and expect to find a schema definition for the DataSet type, this WSDL will be useless. So the question remains, can you use .NET Remoting to build Web services? Yes, strictly speaking, you can. But, will anybody who is not using the .NET Remoting plumbing be able to use them? The answer is maybe, if you are careful to pare down your endpoint to bare bones data types and semantics. Specifically, if you want interoperability with other Web service toolkits, you need to restrict parameters to the built-in simple types and your own data types (don't use .NET Framework types like DataSet), and avoid client-activated objects and events. In short, if you care about reach, you need to restrict yourself to the same set of functionality that ASP.NET Web services support. Or better yet, use ASP.NET Web Services, because this is exactly what they are designed for.
Security
Since ASP.NET Web services rely on HTTP, they integrate with the standard Internet security infrastructure. ASP.NET leverages the security features available with IIS to provide strong support for standard HTTP authentication schemes including Basic, Digest, digital certificates, and even Microsoft .NET Passport. (You can also use Windows Integrated authentication, but only for clients in a trusted domain.) One advantage of using the available HTTP authentication schemes is that no code change is required in a Web service; IIS performs authentication before the ASP.NET Web services are called. ASP.NET also provides support for .NET Passport-based authentication and other custom authentication schemes. ASP.NET supports access control based on target URLs, and by integrating with the .NET code access security (CAS) infrastructure. SSL can be used to ensure private communication over the wire. Although these standard transport-level techniques to secure Web services are quite effective, they only go so far. In complex scenarios involving multiple Web services in different trust domains, you have to build custom ad hoc solutions. Microsoft and others are working on a set of security
specifications that build on the extensibility of SOAP messages to offer message-level security capabilities. One of these is the XML Web Services Security Language (WS-Security), which defines a framework for message-level credential transfer, message integrity, and message confidentiality. As noted in the previous section, the .NET Remoting plumbing does not secure cross-process invocations in the general case. A .NET Remoting endpoint hosted in IIS with ASP.NET can leverage all the same security features available to ASP.NET Web services, including support for secure communication over the wire using SSL. If you are using the TCP channel or the HTTP channel hosted in processes other than aspnet_wp.exe, you have to implement authentication, authorization and privacy mechanisms yourself. One additional security concern is the ability to execute code from a semi-trusted environment without having to change the default security policy. ASP.NET Web Services client proxies work in these environments, but .NET Remoting proxies do not. In order to use a .NET Remoting proxy from a semi-trusted environment, you need a special serialization permission that is not given to code loaded from your intranet or the Internet by default. If you want to use a .NET Remoting client from within a semi-trusted environment, you have to alter the default security policy for code loaded from those zones. In situations where you are connecting to systems from clients running in a sandboxlike a downloaded Windows Forms application, for instanceASP.NET Web Services are a simpler choice because security policy changes are not required.
State Management
The ASP.NET Web Services model assumes stateless service architecture by default; it does not inherently correlate multiple calls from the same user. In addition, each time a client invokes an ASP.NET Web service, a new object is created to service the request. The object is destroyed after the method call completes. To maintain state between requests, you can either use the same techniques used by ASP.NET pages, i.e., the Session and Application property bags, or you can implement your own custom solution. .NET Remoting supports a range of state management options and may or may not correlate multiple calls from the same user, depending on what object lifetime scheme you choose. SingleCall objects are stateless (like the objects used to invoke ASP.NET Web services), Singleton objects share state for all clients, and client-activated objects maintain state on a per-client basis (with all the associated scalability and reliability issues this raises).
Performance
In terms of raw performance, the .NET Remoting plumbing provides the fastest communication when you use the TCP channel and the binary formatter. In almost all the tests that we carried out to compare the relative performance of ASP.NET Web services and .NET Remoting, ASP.NET Web services outperformed .NET Remoting endpoints that used the SOAP formatter with either the HTTP or the TCP channel. More interestingly, ASP.NET and .NET Remoting endpoints that used the binary formatter and the HTTP channel were very similar in performance. (See Performance Comparison: .NET Remoting vs. ASP.NET Web Services for more details.)
Enterprise Services
An ASP.NET Web Service or an object exposed via .NET Remoting can use local transactions to coordinate work against a single database. If it needs to coordinate work against multiple resources, it can use a .NET Enterprise Services (a.k.a. COM+) declarative transaction (a DTC distributed transaction managed by the COM+ plumbing). It is important to note, however, that neither the ASP.NET Web services nor the .NET Remoting plumbing supports propagating a declarative
transaction, so it is impossible for either sort of endpoint to inherit a declarative transaction via a cross-process call. This is not necessarily a bad thing. In general, a declarative transaction is more expensive than a local transaction and if you spread a declarative transaction across process boundaries, it becomes more expensive still. If you really need this functionality, the easy solution is to deploy a class derived from System.EnterpriseServices.ServicedComponent in a .NET Enterprise Services server application (see COM+ Integration: How .NET Enterprise Services Can Help You Build Distributed Applications for more information). Cross-process calls to the objects of that type will be handled using DCOM in order to ensure proper propagation of transactional context. The harder solution is to use lower-level APIs to propagate a distributed transaction by hand. It is important to note that the classic distributed transaction model is generally not appropriate for loosely coupled Web services. A model based on compensating transactions, that is, transactions that undo the committed work of other transactions, make more sense because they have less stringent isolation constraints. There is a general consensus among Web service vendors, including Microsoft, that a more flexible transaction model is needed in the Web services space, and there is a lot of ongoing work in this space. Until a standard approach for Web service transactions is defined, you can implement your own compensation schemes using local or declarative transactions as appropriate.
Choosing an Architecture
If you are designing a distributed application built on .NET, you have to consider all of the issues discussed in this paper and draw some conclusions about what your system's architecture should look like. In general, this turns out to be easier than you might think. While there is always a special case that requires an alternate approach, here are some general assumptions you can make that will simplify things for you. First, use ASP.NET Web services by default. They are simpler to implement and use, they offer the broadest possible reach to client platforms, and ASP.NET Web services client proxy code can be invoked from code run in a sandbox under the default security policy. If you need a more traditional distributed object model with full CLR type fidelity, you don't need interoperability with other platforms, and you control the configuration of both clients and servers, consider .NET Remoting. If you choose .NET Remoting, prefer the HTTP channel integrated with IIS and ASP.NET, otherwise you have to build your own process lifecycle management and security infrastructure. Given that .NET Remoting requires a .NET client, it makes sense to use the binary formatter instead of the SOAP formatter; interoperability is not an issue and performance will be noticeably better. Finally, use Enterprise Services (COM+) when you need declarative transactions. If you implement ServicedComponents, deploy them in library applications by default, for performance reasons. Deploy them in server applications if they need to run on remote machines. (You might also consider COM+ server applications if you need to execute code with a different process security token than the one used by aspnet_wp.exe, even on the same machine.) Here are three common architectures based on these ideas. Figure 1. A simple 3-tier architecture Figure 1 shows a simple 3-tier architecture with a Web server farm supporting a range of different clients. All server-side code executes in the ASP.NET worker process, aspnet_wp.exe. The three different types of clients access the server farm by using HTTP. Browser-based clients invoke ASP.NET Web pages; rich clients (e.g., Windows Forms applications, Microsoft Visual Basic 6 applications) and other Web services use ASP.NET Web services; and .NET rich clients (e.g.,
Windows Forms applications) and Web services use ASP.NET Web services or .NET Remoting with the HTTP channel and the binary formatter (assuming it is not in a sandbox), as desired. Figure 2. An n-tier architecture using ASP.NET Some very large applications use a second set of machines to offload work from the outer tier of Web servers. This architecture is shown in Figure 2. Note that in this case, the second tier exposes functionality through ASP.NET as well. Figure 3. An n-tier architecture using Enterprise Services (COM+) Figure 3 shows an alternative version of this architecture with the second tier exposing functionality using ServicedComponents deployed in COM+. Obviously, these are not all of the possible architectures that the .NET Framework supports. However, they provide a reasonable place to start in the design of your own systems.
Summary
Though both the .NET Remoting infrastructure and ASP.NET Web services can enable crossprocess communication, each is designed to benefit a different target audience. ASP.NET Web services provide a simple programming model and a wide reach. .NET Remoting provides a more complex programming model and has a much narrower reach. It is important to understand how both technologies work and to choose the one that is right for your application. In either case, expect to use IIS and ASP.NET to manage process lifecycle and provide security in the general case.