300 likes | 420 Views
More on Web Services. Maintaining State Legacy Code Asynchronous Calls. 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?
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