Basic Client and Service Working with the .NET Service Bus

Our goal here is organic. It is the fundamental “Hello World” in terms of communications.

Access Control Service, Relay Service

This blog entry introduces an authenticating mechanism, which determines which clients can connect to our service.

We also introduce a relay service, which now makes it possibles to connect two or more parties, regardless of whether any connections are behind any firewall, NAT device, switch, or router.

The code below is simple - some service that exposes some endpoint, some protocol, some security model. That service is secure and can be reached by almost any client on earth.

Primarily it is about using Azure and it’s fundamental relationship to the AppFabric.

The application we are about to write will allow this person to send the name of a city to our weather service, and our weather service responds with a string about weather conditions for the city name passed in.

image

https://brunoblogfiles.com/Projects/WeatherClientService/Service.zip

 

image

image

Step 1: The client sends the string “Novato” (or some other city) to the Service.

Step 2: The Service takes that city, goes to a web site that has weather about that city.

Step 3: The Service scrapes the weather from the screen and sends back to client.

image 

The AppFabric is hugely important.

image

The logical view abstracts the relay and access control service away to give us this clean depiction. No view of the relay service or the access control service here. We just see the ability to send and receive messages between client and server.

image

The Infrastructure for the Service Bus

Here we can see that a whole infrastructure is transparently available to the developer.

This infrastructure makes it easy to model client / server scenarios without worrying about NATs, Firewalls, routers, and switches. From the server side, your service will expose an authenticated endpoint. From the client, you will connect to the endpoint.

Notice the client interacting with the service and the use of (1) access control service; (2) relay service.

 

image

 

 

Download the Windows Azure Platform Training Toolkit

There are a great many hands-on labs that I used to help generate my samples. It is a great kit and I thank all those who created it.

Untitled-1 

Many argue that the .NET Service Bus is the most important part of the Windows Azure Platform. I call it the glue that binds the world, everything from your on-premise apps to your apps in the cloud. I’m I think any cloud is appropriate. There are enough flexible client-side libraries in multiple languages that the world is your pearl. You can connect everything to everything.

Relay or Tunnel

Typically, connecting two computers over a switch and firewall or router is complex. The .NET Service Bus gives us the ability insert an intermediary between two computers to dramatically simplify communications. There is also some sophisticated communications built into the .NET Service Bus to allow a direct peer-to-peer connection. We can talk about “Hybrid” connections in a future blog post.

The goal is simple

The goal is to interconnect different applications securely without the need to write and maintain complex logic and code to traverse networks. It is that simple everybody.

The infrastructure for security is there

Identity and authentication management service is easily integrated into your applications. You can apply security to traditional SOAP-based connections or REST-based interfaces.

The Access Control Service is all about give you a token if you have the rights to. That token is then used to communicate with the service via a “Relay Service.” That means all messages go through an intermediary (unless you upgrade to a direct peer to peer).

 Getting started

Here are the three parts of this blog

image

So let’s get started

image

Login with a previously created live id, go to https://windows.azure.com

 Untitled-1

Here is our portal, which describes our basic project.

Right below “Project Name” you will see “Basic Chat Application.” I created this previously. There is very little to creating a project in AppFabric.

Untitled-1

Here is where I take note of brunochat.

Also notice the “Default Issuer Name” and the “Default Issuer Key.” We will need those when we build the client and the server (aka “Service”).

We need to take note of names and security information from the web portal

Untitled-1

 About the Token

It is a security token (called Simple Web Token) that is then trusted by the service itself.

image

Start Visual Studio 2010 Beta 2. It is free to download. Start as “administrator.”

Quick Review
We have completed

We have gotten our

(1) Service namespace,

(2) Default Issuer Name

(3) Default Issuer Key

   
We are now doing Create a new Visual Studio Project
   
What we will do next Implement our code for Client and Server

Start Visual Studio 2010

Untitled-1

1. On the File menu, point to New, and click Project. In the New Project dialog box, select Visual C# | Windows. Make sure that .NET Framework 3.5 is selected and choose the Console Application project type. Set the project name to Service.

Untitled-1

Nothing surprising here. Just a simple console app with the entry point - “main.”

image

Connecting to useful DLLs - Adding a reference

2. Add a reference to System.ServiceModel.dll assembly. After all, we are programming WCF Services. I am using VS 2010 Beta 2, which saves me from browsing. Those of you using VS 2008 will need to find the SDK and the physical file System.ServiceModel.dll. System.ServiceModel.dll is one of WCF core assemblies.

image

Also, add “System.Drawing.”

image 

3. Create the WCF service contract. A service contract specifies what an endpoint communicates to the outside world. When you build it you define how it will behave in terms of request/reply, one-way, or duplex.

Also remember your ABCs

The ABC of Windows Communication Foundation

"ABC" is the WCF mantra. "ABC" is the key to understanding how a WCF service endpoint is composed. 

  • "A" stands for Address: Where is the service?
  • "B" stands for Binding: How do I talk to the service?
  • "C" stands for Contract: What can the service do for me?

Therefore, right now we are talking about the “C” or contract part.

image

Source code coming soon

The source code is posted below (later in this blog entry).

 

Quick Review
We have completed

(1) We have completed a new project (Console app, called “Service”)

(2) We have added a contract (IEchoContract) that the client will use to communicate with the service.

   
We are now doing Adding a Channel to the project
   
What we will do next Implement the Channel

Why are we adding a channel?

This application leverages Channels, one of the fundamental pillars of the AppFabric.

     
  Channel Responsibilities   
  Sending and receiving messages to and from other parties  
  Transforming the Message object to and from the format used to communicate with other parties  
  Adding headers or encrypting the body  
  Sending and receiving their own protocol control messages, for example, receipt acknowledgments  
     

4. Now add another interface. Call it IEchoChannel.cs

image

Adding a class module

5. Add a class module. Call it EchoService.

image

Give it the name “EchoService.”

image

image 

Now you can see our two interfaces (IEchoChannel, IEchoContract) and the class (EchoService).

image

Now the source code.

 image

The screen scraping class is in "class MyWeatherData." It has about 4 private variables to help with the scraping of weather data from a web page.
        private string rawHtml;
        private string result;
        private string url;
        private string data;

EchoService contains the class MyWeatherData. MyWeatherData is what actually does the lookup of a city and "scrape" the information from the web page to return to the client.

I recommend you set breakpoints on one of the functions, such as "GetHiRaw()" to see what is happening in the code. You will note the use of "Regular Expressions" (RegEx) in the code.

Notice the code snippet below that searches through matches. It is a very convenient and terse way to parse out a web page.

Code Snippet

  1. SortedList uniqueMatches = new SortedList();
  2. Match[] retArray = null;
  3. Regex RE = new Regex(matchPattern, RegexOptions.Multiline);
  4. MatchCollection theMatches = RE.Matches(source);
  5. if (findAllUnique)
  6. {
  7.     for (int counter = 0; counter < theMatches.Count; counter++)
  8.     {
  9.         if (!uniqueMatches.ContainsKey(theMatches[counter].Value))
  10.         {
  11.             uniqueMatches.Add(theMatches[counter].Value,
  12.             theMatches[counter]);
  13.         }
  14.     }
  15.     retArray = new Match[uniqueMatches.Count];
  16.     uniqueMatches.Values.CopyTo(retArray, 0);
  17. }

Of course if the external web site I'm using to scrape weather data changes it's layout, I am out of luck. What I could do is find a weather "service," which abstracts away the vagueries of html.

image

  “EchoService” in the project “Service”

Code Snippet

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. // Need to add "using"
  7. using System.ServiceModel;
  8.  
  9. using System.IO;
  10. using System.Net;
  11. using System.Text.RegularExpressions;
  12. using System.Collections;
  13. using System.Collections.Specialized;
  14.  
  15. using System.Drawing;
  16.  
  17.  
  18. namespace Service
  19. {
  20.     class MyWeatherData
  21.     {
  22.         private string rawHtml;        // private Global variable to store a copy of returned raw HTML
  23.         private string result;
  24.         private string url;
  25.         private string data;
  26.  
  27.         public string Data
  28.         {
  29.             get { return data; }
  30.             set { data = value; }
  31.         }
  32.         public string state;
  33.  
  34.         public MyWeatherData(string city, string zip)
  35.         {
  36.             //url = "https://weather.cnn.com/weather/forecast.jsp?locCode=CAPT&zipCode=" + zip;
  37.  
  38.             if (zip == "94945")
  39.             {
  40.                 url = "https://weather.cnn.com/weather/forecast.jsp?locCode=056&zipCode=94998"; //novato
  41.                 state = "good";
  42.             }
  43.             else
  44.             {
  45.                 state = "Unrecognized zip code = " + zip;
  46.                 return;
  47.             }
  48.  
  49.  
  50.  
  51.             WebRequest objRequest = HttpWebRequest.Create(url);
  52.  
  53.             WebResponse objResponse = objRequest.GetResponse();
  54.             Stream stream = objResponse.GetResponseStream();
  55.             StreamReader sr = new StreamReader(stream);
  56.             result = sr.ReadToEnd();
  57.             rawHtml = result.ToLower();
  58.             SetupData(rawHtml);
  59.             objResponse.Close();
  60.         }
  61.         public Image GetImageFromUrl(string url)
  62.         {
  63.             url = "https://www.ssd.noaa.gov/goes/west/nepac/avn-l.jpg";
  64.             WebClient wc = new WebClient();
  65.             Stream st = wc.OpenRead(url);
  66.             Image im = Image.FromStream(st);
  67.             st.Close();
  68.             return im;
  69.         }
  70.  
  71.  
  72.         public string SetupData(string rawHtml)
  73.         {
  74.             Regex regex = new Regex("<div id=\"cnnWeatherForecastCurrentContent\">((.|\n)*?)<div class=\"cnnWireBoxFooter\">",
  75.                                     RegexOptions.IgnoreCase);
  76.  
  77.             Match oM = regex.Match(rawHtml);
  78.             string newResults = oM.Value;
  79.  
  80.  
  81.             data += GetHiRaw(newResults);
  82.             data += GetLowRaw(newResults);
  83.             data += GetBarometer(newResults);
  84.             data += GetCloudCondition(newResults);
  85.             data += GetHumidity(newResults);
  86.             data += GetFeelsLike(newResults);
  87.  
  88.  
  89.             return data;
  90.         }
  91.  
  92.         public static Match[] FindSubstrings(string source,
  93.                string matchPattern, bool findAllUnique)
  94.         {
  95.             SortedList uniqueMatches = new SortedList();
  96.             Match[] retArray = null;
  97.             Regex RE = new Regex(matchPattern, RegexOptions.Multiline);
  98.             MatchCollection theMatches = RE.Matches(source);
  99.             if (findAllUnique)
  100.             {
  101.                 for (int counter = 0; counter < theMatches.Count; counter++)
  102.                 {
  103.                     if (!uniqueMatches.ContainsKey(theMatches[counter].Value))
  104.                     {
  105.                         uniqueMatches.Add(theMatches[counter].Value,
  106.                         theMatches[counter]);
  107.                     }
  108.                 }
  109.                 retArray = new Match[uniqueMatches.Count];
  110.                 uniqueMatches.Values.CopyTo(retArray, 0);
  111.             }
  112.             else
  113.             {
  114.                 retArray = new Match[theMatches.Count];
  115.                 theMatches.CopyTo(retArray, 0);
  116.             }
  117.             return (retArray);
  118.         }
  119.  
  120.  
  121.         #region Get raw text code functions
  122.  
  123.         public string AddSpaces(int len, string the_temp)
  124.         {
  125.             if (the_temp.Length > 30)
  126.                 return "<error>";
  127.  
  128.             int sp = 40 - len;
  129.  
  130.             return "".PadLeft(sp) + the_temp;
  131.         }
  132.  
  133.  
  134.         public string GetHiRaw(string rawHtml)
  135.         {
  136.             string front_part = "<b>hi ";
  137.             string end_part = "&deg";
  138.             string msg = "Hi temp: ";
  139.             string end_msg = " degrees";
  140.             string result = fetchValue(front_part, end_part, msg, end_msg, rawHtml);
  141.             return result;
  142.  
  143.  
  144.         }
  145.  
  146.         public string GetBarometer(string rawHtml)
  147.         {
  148.             string front_part = "<b>barometer: </b>";
  149.             string end_part = "\" hg\r\n";
  150.             string msg = "Barometer: ";
  151.             string end_msg = " hg";
  152.             string result = fetchValue(front_part, end_part, msg, end_msg, rawHtml);
  153.             return result;
  154.  
  155.  
  156.         }
  157.  
  158.  
  159.         public string fetchValue(string front_part, string end_part, string msg, string end_msg, string rawHtml)
  160.         {
  161.             string matchPattern = front_part + "((.|\n)*?)" + end_part;
  162.  
  163.             Match[] x1 = FindSubstrings(rawHtml, matchPattern, false);
  164.  
  165.             StringBuilder sb = new StringBuilder();
  166.  
  167.             foreach (Match m in x1)
  168.             {
  169.                 sb.Append(m.Value);
  170.  
  171.             }
  172.             string s = sb.ToString();
  173.  
  174.             int start = s.IndexOf(front_part) + front_part.Length;
  175.             int end = s.IndexOf(end_part);
  176.  
  177.             string the_value = s.Substring(start, end - start);
  178.  
  179.             return msg + AddSpaces(msg.Length, the_value) + end_msg + "\n";
  180.  
  181.         }
  182.  
  183.         public string GetLowRaw(string rawHtml)
  184.         {
  185.             string front_part = "<b>lo ";
  186.             string end_part = "&deg";
  187.             string msg = "Low temp: ";
  188.             string end_msg = " degrees";
  189.             string result = fetchValue(front_part, end_part, msg, end_msg, rawHtml);
  190.             return result;
  191.  
  192.  
  193.         }
  194.  
  195.         public string GetCloudCondition(string rawHtml)
  196.         {
  197.             string front_part = "</div>\r\n\t\t\t\t<span class=\"cnnweatherconditioncurrent\">";
  198.             string end_part = "</span>";
  199.             string msg = "Overall: ";
  200.             string end_msg = "";
  201.             string result = fetchValue(front_part, end_part, msg, end_msg, rawHtml);
  202.             return result;
  203.  
  204.  
  205.         }
  206.         public string GetHumidity(string rawHtml)
  207.         {
  208.             string front_part = "<b>humidity: </b>";
  209.             string end_part = "%<br />";
  210.             string msg = "Humidity: ";
  211.             string end_msg = " %";
  212.             string result = fetchValue(front_part, end_part, msg, end_msg, rawHtml);
  213.             return result;
  214.  
  215.  
  216.         }
  217.         public string GetFeelsLike(string rawHtml)
  218.         {
  219.             string front_part = "<b>feels like: </b>";
  220.             string end_part = "&deg;<br />";
  221.             string msg = "Feels like: ";
  222.             string end_msg = " degrees";
  223.             string result = fetchValue(front_part, end_part, msg, end_msg, rawHtml);
  224.             return result;
  225.         }
  226.         #endregion
  227.         public string GetHtml()
  228.         {
  229.             return data;
  230.         }
  231.  
  232.     }
  233.  
  234.     // Add this attribute
  235.     [ServiceBehavior(Name = "EchoService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
  236.     public class EchoService : IEchoContract   // Inherit from IEchoContract
  237.     {
  238.         // Implement the contract method
  239.         public string Echo(string text)
  240.         {
  241.             MyWeatherData weather_data = new MyWeatherData("", "94945");
  242.             if (weather_data.state != "good")
  243.                 return "Error with \"" + text + "\", " + weather_data.state;
  244.  
  245.             Console.WriteLine("Echoing: \n{0}", weather_data.Data);
  246.             return weather_data.Data;
  247.         }
  248.         // Implement the contract method
  249.         public Image EchoImage(string text)
  250.         {
  251.             MyWeatherData weather_data = new MyWeatherData("", "94945");
  252.             return weather_data.GetImageFromUrl("https://www.ssd.noaa.gov/goes/west/nepac/avn-l.jpg");
  253.         }
  254.     }
  255. }

 

image

Code Snippet

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6.  
  7. // Need to add the "using"
  8. using System.ServiceModel;
  9.  
  10. namespace Service
  11. {
  12.     public interface IEchoChannel : IEchoContract, IClientChannel
  13.     {
  14.     }
  15. }

image

Code Snippet

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. // Need to add the "using"
  7. using System.ServiceModel;
  8. using System.Drawing;
  9. namespace Service
  10. {
  11.     // Add the ServiceContract.
  12.     [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
  13.     public interface IEchoContract
  14.     {
  15.         [OperationContract]
  16.         string Echo(string text);
  17.         [OperationContract]
  18.         Image EchoImage(string text);
  19.     }
  20. }

It is time to compile. I like to compile frequently to see if I missed anything.

image

Here is what I like to see when I view the “Output Window.”

image

Here’s where we are at.

Quick Review
We have completed

(1) We have added a big chunk of code to Service.

(2) We have added to interfaces and one class module

(3) We have the methods ready to return weather information to the client

   
We are now doing Writing the main driver code. We still don’t have any authentication taking place, the code to open a channel, etc.
   
What we will do next Finish wiring up the “Service” side. Next we will build the “Client” side.

Scraping Weather

Note this code snippet below. It allows us to scrape the weather from a web page at CNN.

image

Before what we start any coding, we need to set a couple of things. First, make sure you’ve installed the .NET Services SDK.

Untitled-1

You will need that installed so you can set a reference to Microsoft.ServiceBus.dll

image

Adding a reference to Microsoft.ServiceBus.dll  Navigate to the folder where the .NET Services SDK got installed.

Untitled-1

image

 

image 

Add some code to main() as follows:

image

 

How our application interacts with the service bus

Your application interacts with the AppFabric Service Bus via the Microsoft.ServiceBus.dll

We will work with the authentication features available through the Windows Azure platform AppFabric.

The binding being used is WebHttpRelayBinding, which is the default binding for web applications.

Why WebHttpRelayBinding?

WebHttpRelayBinding has been created to meet the most common scenarios. Most commonly, Web-style clients talk to services that choose to accept all incoming traffic and perform only lightweight authentication using a variety of custom techniques to enable and enrich AJAX-style user experiences.

The serviceNamespaceDomain
  Got it at the Microsoft portal
The issuerName
  Got it at the Microsoft portal
The issuerSecret
  Got it at the Microsoft portal

Untitled-1 

Main Driver Loop. I have broken it down into 4 parts.

  1. Part 1 – Utilize your namespace

image

The Service will expose endpoints.  But before those endpoints can be exposed we need to configure those endpoints to use some credentials and to be discoverable by a client.

Where endpoints are defined

The service host has endpoints to configure in App.config.

image

The first part of the code establishes the issuerName and the issuerSecret. This can be obtained from the Microsoft Web Portal for Azure. Later it will be part of the endpoints to enforce security for client connections.

------------------------- Part 1 of main()-------------------------Project = “Service”Module = “Program.cs”Function = “main()” Code Snippet
  1. string serviceNamespaceDomain = "brunochat";
  2. string issuerName = "owner";
  3. string issuerSecret = "asdf345345kIAdfsaAakaE32fasdfjkd8f7alkd8addd";

The code below is exposing and endpoint by leveraging the following Azure’s AppFabric Framework:

  • CreateServiceUri()
  • TransportClientEndpointBehavior()
------------------------- Part 2 of main()-------------------------Project = “Service”Module = “Program.cs”Function = “main()” Code Snippet
  1. // Constructs the AppFabric Service Bus URI for an application, using the
  2. // specified scheme, service namespace name, and service path.
  3. // The scheme is "sb"
  4. // The solution is something like sb://<DOMAIN>.servicebus.windows.net/
  5. // The service path is "EchoService," which is the name of a class EchoService.cs
  6.  
  7. // returnValue = ServiceBusEnvironment.CreateServiceUri(scheme, solutionName, servicePath)
  8. // sb://<serviceNamespace>.servicebus.windows.net/EchoService/
  9.  
  10.  
  11. Uri address = ServiceBusEnvironment.CreateServiceUri("sb",
  12.               serviceNamespaceDomain, "EchoService");
  13.  
  14. // Create the credential object for the endpoint. You've entered these values on the
  15. // command line above.
  16. // Service Bus supports only Full Trust code access security.
  17. TransportClientEndpointBehavior sharedSecretServiceBusCredential =
  18.                                               new TransportClientEndpointBehavior();
  19. sharedSecretServiceBusCredential.CredentialType = TransportClientCredentialType.SharedSecret;
  20. sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName = issuerName;
  21. sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret = issuerSecret;

Here we setup the actual host of “EchoService.”

Code Review
We have completed

(1) We are finishing up the details for our “Service,” specifically the configuration of endpoint attributes, such as security and discoverability

(2) We are using our security credentials that we retrieved from the web portal for Azure App Fabric

   
We are now doing

(1) Writing the main driver code.

(2) We now need to setup our endpoints by looping through them

(3) We are ensuring that the endpoint is published into the discovery feed so clients can see it

(4) We also need to set security attributes from each endpoint

   
What we will do next (1) Open ServiceHost when we are done setting up endpoints

 

------------------------- Part 3 of main()-------------------------Project = “Service”Module = “Program.cs”Function = “main()” Code Snippet
  1. // Create the service host reading the configuration. This means that outside
  2. // clients will try to connect
  3. // to this endpoint.
  4. ServiceHost host = new ServiceHost(typeof(EchoService), address);
  5.  
  6. // Create the ServiceRegistrySettings behavior for the endpoint
  7. IEndpointBehavior serviceRegistrySettings =
  8.                         new ServiceRegistrySettings(DiscoveryType.Public);
  9.  
  10.  
  11. // add the Service Bus credentials to all endpoints specified in configuration
  12. foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
  13. {
  14.     endpoint.Behaviors.Add(serviceRegistrySettings);
  15.     endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
  16. }

 

Soon, we will begin working on the client. We are pretty much ready to open the endpoints and wait for clients to come in.

Code Review
We have completed

(1) We are finished setting up the Service prior to being opened

   
We are now doing

(1) Simply open the service and wait for connections

   
What we will do next Start working on the client code

 

------------------------- Part 4 of main()-------------------------Project = “Service”Module = “Program.cs”Function = “main()” Code Snippet
  1. // Open the service
  2. host.Open();
  3. Console.WriteLine("Service address: " + address);
  4. Console.WriteLine("Press [Enter] to exit");
  5. Console.ReadLine();
  6. // Close the service
  7. host.Close();

 

 

image

1. Right-click Service project, point to Add and select New Item. In the Add New Item dialog box, select the Application Configuration File template, leave the name by default and click Add

Notice we are defining the contract and the binding. Remember that WCF is about the ABCs. Address, Binding, Contract.

Endpoint

  • Contract = Service.IEchoContract
  • binding = netTcpRelayBinding

NetTcpRelayBinding Class

[This is prerelease documentation and is subject to change in future releases. Blank topics are included as placeholders.]

A secure, reliable binding suitable for cross-machine communication.

Namespace: Microsoft.ServiceBusAssembly: Microsoft.ServiceBus (in microsoft.servicebus.dll)

 

image 

Code Snippet

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <system.serviceModel>
  4.     <services>
  5.       <service name="Service.EchoService">
  6.         <endpoint contract="Service.IEchoContract"
  7.             binding="netTcpRelayBinding" />
  8.       </service>
  9.     </services>
  10.   </system.serviceModel>
  11. </configuration>

 

image

Let’s get a few things out of the way. What is the big picture for us to create this client application. Here is the big picture.

image

Here is the breakdown:

Preparation

Understanding what you are connecting to

Retrieve a copy of the contract of the service and place it in your code

Retrieve your service namespace and relevant credential information

Define the security credentials to use with the service

Prepping the client to talk through the service bus - Setting References

Add the System.ServiceModel and Microsoft.ServiceBus namespaces to your project

Defining your connection (Uri, Binding, Channels)

Create an URI object pointing to the service bus service

Define the binding to use to connect to the service

Running the Client

Instantiate a channel factory

Apply the credentials and any other behaviors to the endpoint

Create a new channel to the service and open

Ready to perform business functions

Perform whatever tasks are necessary to your scenario

 What server and client share

Both the server and client pieces define an interface called IEchoChannel, which is a derived interface from IEchoContract and IClientChannel. All together, the IEchoChannel (1) defines the methods that the client will access, and (2) defines the channel by which server and client will communicate.

What is a channel?

The Service Bus (AppFabric) is a layered communication stack with one or more channels that process messages. At the bottom of the stack is a transport channel that is responsible for adapting the channel stack to the underlying transport (for example, TCP, HTTP, SMTP and other types of transport.).

Bottom Line

Channels provide a low-level programming model for sending and receiving messages.

Channels – details about message delivery, protocols used, transports

I like that Channels  abstract away details of protocols, transports, message delivery details.

Channel stack is designed to provide an abstraction of not only how the message is delivered, that is, the transport, but also other features such as what is in the message or what protocol is used for communication, including the transport.

Channel Responsibilities

Sending and receiving messages to and from other parties.

Transforming the Message object to and from the format used to communicate with other parties.

Adding headers or encrypting the body,

Sending and receiving their own protocol control messages, for example, receipt acknowledgments.

Channels handle difference protocols

There can be any number of protocol channels each responsible for providing a communication function such as reliable delivery guarantees.

1. Add a New Project.

You will create the Client project. To do this, in Solution Explorer, right-click Service solution, point to Add and select New Project. In the New Project dialog box, select the Console Application project type. Set the project name to Client, and click OK.

image

Click on ‘Service’ or topmost item in Solution Explorer.

 

image

 

Untitled-1

Choose “Console Application.”

image

2. Create the Echo client proxy. To do this, in Solution Explorer right-click the Client project , point to Add and select New Item. In the Add New Item dialog box, select Visual C# | Code and choose the Interface template. Specify a Name value of EchoProxy.cs. Click Add to create the Interface [illustrated previously].

 

3. Name the interface EchoProxy.cs.

Untitled-1

The client needs to communicate with the server through “pre-agreed” contracts. Our contract is in the form of an interface.

 Adding the client reference

Just as with the server side, we need to provide references to allow our client to use the AppFabric.

4. Add a reference to ServiceModel assembly. To do this, in Solution Explorer, right-click the Client project and select Add Reference. In the Add Reference dialog box, in the .NET tab, select System.ServiceModel assembly. Click OK to add the reference

5. Add references to Microsoft .Net Services SDK core assembly. To do this, right-click Client project in Solution Explorer and select Add Reference. In the Add Reference dialog window:

Untitled-1

image

Adding a reference to Microsoft.ServiceBus.dll  Navigate to the folder where the .NET Services SDK got installed.

 

Here we setup the actual host of “EchoService.”

clip_image002[7]

Code Review

We have completed

(1) The “Service” that the client will connect to is finished

(2) We are done with server side

 

We are now doing

(1) The Client side that connects to the server

(2) Write code to connect to service using security credentials, service name, contract information, etc

 

What we will do next

(1) Run the client and complete this blog entry

 

------------------------- Part 1 of main()-------------------------Project = “Service”Module = “Program.cs”Function = “main()” Code Snippet
  1. string serviceNamespaceDomain = "brunochat";
  2. string issuerName = "owner";
  3. string issuerSecret = "asdf345345kIAdfsaAakaE32fasdfjkd8f7alkd8addd";

 

image

 

 

Code Review

We have completed

(1) We have already setup credentials for endpoints

 

We are now doing

(1) Creating a Channel, which will help us abstract away protocols and other transport details

 

What we will do next

(1) Write the code that reads user input at the client and passes that input to Service

(2) Call the “Echo()” method of our Service

 

------------------------- Part 2 of main()-------------------------Project = “Service”Module = “Program.cs”Function = “main()” Code Snippet
  1. // Constructs the AppFabric Service Bus URI for an application, using the
  2. // specified scheme, service namespace name, and service path.
  3. // The scheme is "sb"
  4. // The solution is something like sb://<DOMAIN>.servicebus.windows.net/
  5. // The service path is "EchoService," which is the name of a class EchoService.cs
  6.  
  7. // returnValue = ServiceBusEnvironment.CreateServiceUri(scheme, solutionName, servicePath)
  8. // sb://<serviceNamespace>.servicebus.windows.net/EchoService/
  9.  
  10.  
  11. Uri address = ServiceBusEnvironment.CreateServiceUri("sb",
  12.               serviceNamespaceDomain, "EchoService");
  13.  
  14. // Create the credential object for the endpoint. You've entered these values on the
  15. // command line above.
  16. // Service Bus supports only Full Trust code access security.
  17. TransportClientEndpointBehavior sharedSecretServiceBusCredential =
  18.                                               new TransportClientEndpointBehavior();
  19. sharedSecretServiceBusCredential.CredentialType = TransportClientCredentialType.SharedSecret;
  20. sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName = issuerName;
  21. sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret = issuerSecret;

 

image

 

 

Code Review

We have completed

(1) Setup our client to connect to the service and prepare to send a string from client to service.

 

We are now doing

(1) Writing code that gets user input from the console window of the client, passes that input to our Service

(2) For example, if the client passes in the zip code for Novato (“94945”) to the Service, the Service will return a string with the weather for Novato

 

What we will do next

(1) x

------------------------- Part 3 of main()-------------------------Project = “Client”Module = “Program.cs”Function = “main()” Code Snippet
  1. #region Part03
  2. Console.WriteLine("Enter text to echo (or [Enter] to exit):");
  3. string input = Console.ReadLine();
  4. while (input != String.Empty)
  5. {
  6.     try
  7.     {
  8.         Console.WriteLine("Server echoed: \n{0}", channel.Echo(input));
  9.     }
  10.     catch (Exception e)
  11.     {
  12.         Console.WriteLine("Error: " + e.Message);
  13.     }
  14.     input = Console.ReadLine();
  15. }
  16.  
  17.  
  18. #endregion

image \

Code Review

We have completed

(1) Written the client code

(2) Used client to connect to Service

(3) Client sends a zip code and receives weather back

 

We are now doing

(1) Closing connections. We are done

 

What we will do next

(1) Re-read this blog entry to learn it better

------------------------- Part 4 of main()-------------------------Project = “Client”Module = “Program.cs”Function = “main()” Code Snippet
  1. #region Part04
  2. channel.Close();
  3. channelFactory.Close();
  4.  
  5. #endregion

 

Don’t be confused about terminology

There are a lot of similar technologies here. WCF, ServiceBus, AppFabric. Do your own research to dis-ambiguate what they mean.

Add a new configuration file.

Untitled-1

Your app.config should like this. Notice that we specify a binding  and a contract.

Code Snippet

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <system.serviceModel>
  4.     <client>
  5.       <!-- Application Endpoint -->
  6.       <endpoint name="RelayEndpoint"
  7.                 contract="Client.IEchoContract"
  8.                 binding="netTcpRelayBinding"/>
  9.     </client>
  10.   </system.serviceModel>
  11. </configuration>

But before compiling we need to adjust the framework that our project compiles against. First, go the “Service” project and right mouse click and choose Properties.

Untitled-1

Make sure you have .NET Framework 3.5 for both the client and service.

Untitled-1

image

1.  Make sure you’ve gone to the web portal and registered a project. As you can see I have clicked on “App Fabric” to get things started.

Run the Service. To do this, right-click Service project, point to Debug and select StartNewInstance.

Note that we have various management keys, registered URLs, endpoints, Issuer Keys and Issuer Name. Issuer Keys and Issuer name is what we need to work with our example.

image

https://brunoblogfiles.com/Projects/WeatherClientService/Service.zip