300 likes | 425 Vues
This guide demonstrates how to maintain state in asynchronous web services using session management in .NET. It covers creating a web service object that retains state across multiple client visits using an HTTP session. You will learn to implement a method for storing and retrieving a client's name and handling multiple concurrent clients. The process includes writing a remote object, setting up a virtual directory, generating a client proxy, and executing multiple requests. Ideal for developers transitioning from legacy systems to modern web services with state management.
E N D
More on Web Services Maintaining State Legacy Code Asynchronous Calls MSCF/CMU
State Management • Web Service objects are single call objects • The object is created and destroyed on each visit • Client Activated objects hold state associated with each client • How can we do the same with Web Services? • Use an Http Session object MSCF/CMU
State Management Example • Suppose we need a web service object to store a person’s name. • The name is to be available over many visits from the same client. • More than one client can use the service at the same time. MSCF/CMU
Step by step • Write the remote object that uses a session object • Compile to a .dll and store in a directory named bin • Write a .asmx file and store it in the directory immediately above bin • Build a virtual directory named PersonName and point it at the directory immediately above bin MSCF/CMU
Step by step • Visit http://localhost/PersonName • Click the .asmx file • Experiment with the service • Download the WSDL document • Run wsdl and generate a C# proxy • Compile the proxy to a .dll • Write a client with cookies enabled • Compile with csc –r:theProxy.dll MyClient.cs MSCF/CMU
The Web Service using System; using System.Runtime.Remoting.Lifetime; using System.Web.Services; namespace SessionDemo { public class PersonName : System.Web.Services.WebService { [WebMethod(EnableSession=true)] public void setName(String n) { // write the name to the Session object Session["PersonName"] = n; } MSCF/CMU
[WebMethod(EnableSession=true)] public String getName() { // read from the session object String n = (String)Session["PersonName"]; return n; } } } MSCF/CMU
PersonName.asmx <%@ WebService Language="c#" Class="SessionDemo.PersonName" CodeBehind="PersonName.cs" %> The pointer to the .cs file is misleading. This is used by Visual Studio to switch between views. We are not using Visual Studio here. MSCF/CMU
The Client using System; public class PersonNameClient { static void Main(string[] args) { Console.WriteLine("Visit http://localhost/PersonName"); PersonName p = new PersonName(); p.CookieContainer = new System.Net.CookieContainer(); MSCF/CMU
// make 2000 visits for(int k = 0; k < 2000; k++) { p.setName(""+k); String s = p.getName(); Console.WriteLine("Visit #" + k + " " + s); } } } Test by running the client twice, at the same time and from two different DOS screens. MSCF/CMU
Web Services & Legacy Code • Many web services will be developed from scratch. • Many web services will want to make use of existing code. • Existing code is typically “unmanaged”. • In this demonstration we will use Visual Studio .NET to • create a web service from managed legacy code. • The example will use the genetic algorithm project from the • previous course. MSCF/CMU
C++ As A Web Service • Run Visual Studio .NET • Select New Project • New Project Type = Visual C++ • Template = Managed C++ web service • Enter a file and directory name • Look over the Readme.txt file and the directory structure MSCF/CMU
Files Created (From Readme.txt) ACPlusPlusExample.vcproj -- main project file for VC++ projects -- holds information about the platforms, configurations, and project features selected with the Application Wizard. MSCF/CMU
ACPlusPlusExample.cpp This is the main web source file. The default is a “hello world” application. In this demo, we’ll write some C++ code to this file. MSCF/CMU
ACPlusPlusExample.h -- This header file contains the declarations of the Web Service. The default file contains a function prototype for the hello world web service. -- We’ll add new prototypes (method signatures) to this file. AssemblyInfo.cpp -- Contains custom attributes for modifying assembly metadata. MSCF/CMU
ACPlusPlusExample.vsdisco -- discovery file for your web service. -- through the discovery process Web Service clients learn that a Web Service exists, what its capabilities are, and how to properly interact with it. -- an XML document that contains links to other resources that describe the Web Service. MSCF/CMU
Web.Config -- This file allows you to override the default configuration settings for your service. An .asmx file -- created as a pointer to this web application. MSCF/CMU
Edit the C++ code • Select build • Select Run icon • View the service in a browser • On the client side Run wsdl.exe to create a proxy wsdl -o:Proxy.cs http://localhost/ACPlusPlusExample/ACPlusPlusExample.asmx?WSDL • Write a client that uses the proxy MSCF/CMU
A Client of the Genetic Algorithm using System; public class CallGeneticWebService { public static void Main(string[] args) { double[] values = { 6.5, 1.0, 0.0, 2.0, 7.3, 1.1, 0.0, 2.0, 8.5, 1.15, 1.0, 2.0, 8.7, 1.4, 0.0, 3.0, 9.8, 1.7, 1.0, 3.0, 10.5, 1.8, 1.0, 4.0, 9.5, 1.9, 0.0, 3.0, 12.5, 1.9, 1.0, 4.0, 12.5, 2.1, 2.0, 4.0, 13.7, 2.1, 2.0, 4.0, 15.0, 2.3, 2.0, 4.0 }; MSCF/CMU
Class1 p = new Class1(); string result = p.GeneticAlgorithm(11,3,values); Console.WriteLine(result); } } This will not work without a proxy class generated from the web service WSDL document. MSCF/CMU
MyClient Our data set is 6.5 1 0 2 7.3 1.1 0 2 8.5 1.15 1 2 8.7 1.4 0 3 9.8 1.7 1 3 10.5 1.8 1 4 9.5 1.9 0 3 12.5 1.9 1 4 12.5 2.1 2 4 13.7 2.1 2 4 15 2.3 2 4 MSCF/CMU
Our function is 0.1777 = ((0.907132 + ((0.727165 + x1) + (x2 + ((0.727165 + (((x0 + x2) - (0.172155 * ((0.907132 + (((((x0 + x0) - x1) / x2) + x1) + x2)) + ((((0.727165 + x1) + (x0 + ((0.727165 + 0.727165) + x0))) + x0) – (0.172155 * x0))))) / x2)) + x0)))) + x0) MSCF/CMU
Browser Test and Learn Browser Web Service WSDL = Web Services Description Language WSDL.EXE Proxy code to handle communications and marshalling Of parameters MSCF/CMU
Genetic Client C++ Web Service Proxy SOAP MSCF/CMU
Asynchronous Web Service • The generated proxy contains code for asynchronous calls. • We make a call to the service and then continue executing • We have two ways to get the result: (1) Provide a callback method (2) Call a specific method to get the result MSCF/CMU
A Second Client // AsyncGeneticlient/MyClient.cs // Each method in the proxy has a BeginXXX and EndXXX // where XXX is the name of the web service method. using System; using System.Threading; public class CallGeneticWebServiceAsync { class MyStateObject { public AutoResetEvent Event = new AutoResetEvent(false); public Class1 calc = new Class1(); } MSCF/CMU
public static void MyFinishProc(IAsyncResult iar) { MyStateObject o = (MyStateObject) iar.AsyncState; string result = o.calc.EndGeneticAlgorithm(iar); Console.WriteLine(result); o.Event.Set(); // tell the main thread } MSCF/CMU
public static void Main(string[] args) { double[] values = { 6.5, 1.0, 0.0, 2.0, 7.3, 1.1, 0.0, 2.0, 8.5, 1.15, 1.0, 2.0, 8.7, 1.4, 0.0, 3.0, 9.8, 1.7, 1.0, 3.0, 10.5, 1.8, 1.0, 4.0, 9.5, 1.9, 0.0, 3.0, 12.5, 1.9, 1.0, 4.0, 12.5, 2.1, 2.0, 4.0, 13.7, 2.1, 2.0, 4.0, 15.0, 2.3, 2.0, 4.0 }; MSCF/CMU
MyStateObject stateObject = new MyStateObject(); IAsyncResult iar = stateObject.calc.BeginGeneticAlgorithm(11, 3, values, new AsyncCallback(MyFinishProc), stateObject); Console.WriteLine("Waiting for call back to complete"); stateObject.Event.WaitOne(); } } MSCF/CMU
AsyncGeneticClient>MyClient Waiting for call back to complete Our data set is 6.5 1 0 2 7.3 1.1 0 2 8.5 1.15 1 2 8.7 1.4 0 3 9.8 1.7 1 3 10.5 1.8 1 4 9.5 1.9 0 3 12.5 1.9 1 4 12.5 2.1 2 4 13.7 2.1 2 4 15 2.3 2 4 Our function is 0.213383 = ((((x0 + x0) + x0) + (x1 + (0.569536 * (((((((((x0 + 0.303568) + x0) + x1) / (x0 + x0)) + x0) + 0.303568) + x0) + (x1 + (0.569536 * ((((((x0 + 0.3035 68) + x2) + (x1 + (0.569536 * (((x0 + 0.64922) + x1) / (x0 + x0))))) + 0.64922) + ((x0 + 0.303568) + x0)) / (x0 + x0))))) / (x0 + x0))))) + x2) MSCF/CMU