210 likes | 327 Views
INFOSYS 290, Section 3, Fall 2005 , Web Services: Concepts, Design and Implementation. Lecture 4: Creating Web Services. Adam Blum ablum@good.com. Today’s Content. Creating Web Services Overview Demo Web Service Creation Raw computation Database HTML scraping XML wrapping
E N D
INFOSYS 290, Section 3, Fall 2005, Web Services: Concepts, Design and Implementation Lecture 4: Creating Web Services Adam Blum ablum@good.com
Today’s Content • Creating Web Services Overview • Demo Web Service Creation • Raw computation • Database • HTML scraping • XML wrapping • SOAP web service wrapping • Break To Set Up Environments • MindReef SOAPScope • AboveAll • Visual Studio • Redemo of Consuming Web Services • MindReef • AboveAll • Visual Studio • Lecture: Asynchronous Web Services
Creating Web Services • Create a web service project • Design the interface • Demoing “method-oriented interfaces” today • Place [WebMethod] around the exposed methods • Write your internal logic • Test with Visual Studio and debug
Example Web ServicesDemonstrating Various Techniques • Raw computation • PokerOdds (http://www.sims.berkeley.edu/academics/courses/is290-3/f05/samples/PokerOdds) • Database creation • ProjectTraq • Workouts • XML wrapping • Blogs (http://www.sims.berkeley.edu/academics/courses/is290-3/f05/samples/PokerOdds) • SportsBetLines (http://www.sims.berkeley.edu/academics/courses/is290-3/f05/samples/PokerOdds) • HTML/HTTP scraping • PokerOdds AnalyzeHands() • SOAP web service wrapping • SalesForce
Informational Web Services • QCUD • Multiple records in query • Doesn’t have to have CUD • Richly descriptive records • Generally comes from a persisted store • Contrast with computation or transactional web service
Informational Web Service Examples • Sales accounts, contacts, tasks, opportunities • Project bugs • Helpdesk, customer support items • Blog entries • Newsfeeds
Consuming Web Services • Ad hoc tools and management systems • E.g. MindReef SOAPScope • Forms design environments • E.g. AboveAll Studio • Third generation traditional programming environments • E.g. Visual Studio.NET 2005
Why Asynchronous Web Services? • Speed • Due to overhead of XML and http XML web services can be SLOW • Unpredictability • Your app may be invoking a web service that itself is slow, unreliably available or involves a human in the process • Size • Moving to larger coarsegrained documents and less frequent chatty method calls can introduce more overhead Blocking on downstream services creates instant bottlenecks in your application
Creating Asynchronous Web Services • Write “begin” and “end” methods versus single invocation methods • VisualStudio.NET generates: • public System.IAsyncResult BeginValidateEmailAddress(string emailAddress, System.AsyncCallback callback, object asyncState) { • return this.BeginInvoke("ValidateEmailAddress", new object[] {emailAddress}, callback, asyncState); • } • public CheckEmailResult EndValidateEmailAddress(System.IsyncResult asyncResult) { • object[] results = this.EndInvoke(asyncResult); • return ((CheckEmailResult)(results[0])); • }
Invoking Asynchronous Web Services • Polling • Blocking • Callbacks
Polling // polling version private void Command1_Click(object sender, System.EventArgs e) { emailvalidatorproxy=new Einsteinware.EmailServices(); • int start=DateTime.Now.Second; • IAsyncResult ar=emailvalidatorproxy.BeginValidateEmailAddress(TextBox1.Text,null,null); • while (!ar.IsCompleted){ • //do stuff • } • switch(emailvalidatorproxy.EndValidateEmailAddress(ar)){ • case Einsteinware.CheckEmailResult.Valid: • Label1.Text="Valid"; • break; • default: • Label1.Text="Invalid"; • break; • } }
Blocking • private void Command1_Click(object sender, System.EventArgs e) • { • emailvalidatorproxy=new Einsteinware.EmailServices(); • IAsyncResult ar=emailvalidatorproxy.BeginValidateEmailAddress(TextBox1.Text,cb,emailvalidatorproxy); // do lots of stuff • ar.AsyncWaitHandle.WaitOne(); • switch(response) • { • case Einsteinware.CheckEmailResult.Valid: • Label1.Text="Valid"; • break; • default: • Label1.Text="Invalid"; } • }
WaitHandle Object • WaitOne • Waits for this one handle • WaitAny • Static method which takes array of WaitHandles, returns when any have completed • WaitAll • Returns when all have completed
Invoking with a Callback // callback version private void Command1_Click(object sender, System.EventArgs e) { emailvalidatorproxy=new Einsteinware.EmailServices(); // instantiate the AsyncCallback delegate AsyncCallback cb = new AsyncCallback(EmailvalidatorCallback); int start=DateTime.Now; IAsyncResult ar= emailvalidatorproxy.BeginValidateEmailAddress( TextBox1.Text,cb,null); Label1.Text=Label1.Text + "(" + System.Convert.ToString( DateTime.Now.CompareTo(start) ")"; }
The Callback Itself • public delegate void MyDelegate(Label l,String s); • private void EmailvalidatorCallback(System.IAsyncResult ar) • { • CheckEmailResult response=emailvalidatorproxy.EndValidateEmailAddress(ar); • switch(response) • { • case CheckEmailResult.Valid: • message="Valid"; • break; • … • } • responseLabel.Invoke( • new MyDelegate(DisplayResponse),new object[]{label1,message}); • } • private void DisplayResponse(Label label,String message) • { • label.Text=message; • Form1.ActiveForm.Refresh(); • } Remember: callbacks are on a separate thread and need a way to communicate back to the main thread to display…hence delegates
Using the Async State Object • // using async state to handle two label objects • private void button1_Click(object sender, System.EventArgs e) • { • label1.Text="";label2.Text=""; • emailvalidatorproxy=new Einsteinware.EmailServices(); • IAsyncResult ar= emailvalidatorproxy.BeginValidateEmailAddress( textBox1.Text,new AsyncCallback(EmailvalidatorCallback),label1); • IAsyncResult ar2= emailvalidatorproxy.BeginValidateEmailAddress( textBox1.Text,new AsyncCallback(EmailvalidatorCallback),label2); • }
Callback Using the Async State Object • private void EmailvalidatorCallback(System.IAsyncResult ar) • { • CheckEmailResult response=emailvalidatorproxy.EndValidateEmailAddress(ar); • String message=""; • switch(response) • { • case EinsteinwareCheckEmailResult.Valid: • message="Valid“; break; • case CheckEmailResult.InvalidUser: • message="Invalid user"; • break; • … • } • Label responseLabel = (Label)ar.AsyncState; • responseLabel.Invoke(new MyDelegate(DisplayResponse) ,new object[]{responseLabel,message}); • }
Course Project • Goal • Build “web service consuming” client applications from desktops and mobile devices • Requirements • Use an “informational” web service • Has QCUD (Query, Create, Update and Delete operations) • Query returns MULTIPLE records • Consume web service from AboveAll or Visual Studio for desktop • Consume WS from GoodAccess Web Services or Visual Studio from mobile device • Optionally write or enhance a backend web service • Possibly as a “proxy web service” layer on top of original web service • Only if previous steps are achieved • Demo to class • Write up as three page paper including: architecture and UI design • Team size • Two people per project • Proposal • Due today, will accept later
References • Specs • SOAP Specification, http://www.w3.org/TR/soap/ • WSDL Specification, http://www.w3.org/TR/wsdl • UDDI Specification, http://www.uddi.org/specification.html • Tools • Visual Studio, http://microsoft.com/vstudio • Microsoft Web Services Enhancements • http://msdn.microsoft.com/webservices/building/wse/default.aspx
How To Reach Me • ablum@good.com • 408-396-5490 • Office hours Thursday at 4pm • web-services@sims.berkeley.edu