Tải bản đầy đủ
Objective 3.7: Create and configure a WCF service on Windows Azure

Objective 3.7: Create and configure a WCF service on Windows Azure

Tải bản đầy đủ

MORE INFO  NUGET

For more information on NuGet, see Chapter 5’s objective “Manage packages by using
NuGet.”

The NuGet package Windows Azure Service Bus contains all the assemblies you need to set
up your WCF service for relaying. Take the following service as an example:
[ServiceContract(Namespace = "urn:ps")]
interface ISecretService
{
[OperationContract]
string GetSecretData(int d);
}
interface ISecretServiceChannel : ISecretService, IClientChannel { }

The implementation of this class is simple, but you can imagine using your own, more
complex WCF services here:
class SecretService : ISecretService
{
public string GetSecretData(int d)
{
return string.Format("You passed: {0}", d);
}
}

Now that you have your WCF service, you need to host it just as you would with any other
WCF service. The benefit with using the service bus functionality is that it complements your
already existing WCF bindings. This means that you can expose internal endpoints for your
service that can be used to integrate with on-premise applications and that you can expose
special endpoints to connect to the service bus. To host your service, you create an instance
of a ServiceHost, define your endpoints, and then open your server:
ServiceHost sh = new ServiceHost(typeof(SecretService));
sh.AddServiceEndpoint(
typeof(ISecretService), new NetTcpBinding(),
"net.tcp://localhost:9358/secretservice");
sh.AddServiceEndpoint(
typeof(ISecretService), new NetTcpRelayBinding(),
ServiceBusEnvironment.CreateServiceUri("sb", "wcfonazure", "secretservice"))
.Behaviors.Add(new TransportClientEndpointBehavior
{
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
"owner",
"D1Kmb83CCLrAtz4du9vb3xn99DaM2dH4jQqSec98if4=")
});
sh.Open();

250

CHAPTER 3

Designing and implementing WCF Services

Console.WriteLine("Press ENTER to close");
Console.ReadLine();
sh.Close();

In this example, both an internal endpoint is created and an endpoint that connects to the
Azure Service Bus. By running this code, you automatically create the relay in Azure. When
you close the application, the endpoint will be removed from Azure. This means that relaying
works only when the server application is online.
MORE INFO  BROKERED MESSAGING

If relaying is not suited for your type of application because of the need to be online at all
times, you can also look at the brokered messaging capabilities of the Azure Service Bus.
To get started with brokered messaging, you can look at http://msdn.microsoft.com/en-us/
library/windowsazure/hh367516.aspx.

Instead of specifying these endpoints in your code, you can configure them from your
App.config just as you can do with other bindings:


binding="netTcpRelayBinding"
address="sb://wcfonazure.servicebus.windows.net/secretservice"
behaviorConfiguration="sbTokenProvider"/>







issuerSecret="D1Kmb83CCLrAtz4du9vb3xn99DaM2dH4jQqSec98if4=" />






As you can see in both the code and the App.config file, you use two important values: the
name of your service and the Default Key. How to obtain those values is the topic of the next
section.
This example uses the netTcpRelayBinding binding. There are other bindings that you can
use depending on the scenarios you want to support. Microsoft recommends using the netTcpRelayBinding unless you have other specific requirements.



Objective 3.7: Create and configure a WCF service on Windows Azure

CHAPTER 3

251

One of the key features of the Azure Service Bus is its capability to create secure connections through a firewall. This means that you won’t have to make any changes to your onpremise configuration to allow the Service Bus to communicate with your service. Normally,
this is done using TCP ports (both over SSL or unencrypted). If those ports aren’t available,
relaying can also use the default HTPP (port 80) or HTTPS (port 443) ports.
MORE INFO  OTHER BINDINGS

Relayed messaging offers you other bindings that you can use such as BasicHttpRelayBinding, NetOneWayRelayBinding, and NetEventRelayBinding. You can find more information
on these bindings at http://msdn.microsoft.com/en-us/library/windowsazure/hh410102.
aspx.

Relaying bindings to Azure using service bus endpoints
To create a service bus endpoint in Windows Azure, you can go to the management portal
to create a new service bus. When creating a service bus, you specify a namespace and the
region where you want to deploy your service bus. Just as with other Azure components, it’s
wise to create them in the same datacenter. This avoids latency issues and additional costs for
sending data from one datacenter to another.
The Windows Azure portal gives you detailed connection information that you can use
from your server and client services. For example, the connection information for the wcfonazure namespace gives you the following connection string:
Endpoint=sb://wcfonazure.servicebus.windows.net/;SharedSecretIssuer=owner;
SharedSecretValue=D1Kmb83CCLrAtz4du9vb3xn99DaM2dH4jQqSec98if4=

This connection string contains the name of your namespace and the default key. You
need to use those values to configure your server and client applications.
When your relaying host is running, you can also use the Windows Azure Management
Portal to inspect your relay. You can see the name of your relay and how many listeners are
active. When you close the host, the relay disappears from Windows Azure. This also shows
why this feature can help clients who are not willing to store data in the public cloud. By using
the service bus, they have total control over their services hosted in their own datacenter. If
they want, they can shut down their hosts and disconnect themselves from Azure.

Integrating with the Azure service bus relay
After creating a new service bus on Azure and hosting a WCF service with service bus endpoints, you can create a client to communicate with your on-premise service through Azure.
When building a client to communicate with your relay, you need the namespace name
that you used for hosting the service and the default key. This also means you shouldn’t publicly expose these values because if you do, everyone would be able to access your service.

252

CHAPTER 3

Designing and implementing WCF Services

Using the name of your namespace, the owners name (default: owner), and the Default Key,
you use a security mechanism that resembles the idea of a username and password. There are
more elaborate security mechanisms if you need them, such as SAML or SimpleWebToken.
MORE INFO  SECURING YOUR CONNECTION

For more information on securing your service bus connection, see http://msdn.microsoft.
com/en-us/library/windowsazure/dd582773.aspx.

The following code shows how to create a client to call the SecretService that you saw
previously:
var cf = new ChannelFactory(
new NetTcpRelayBinding(),
new EndpointAddress(ServiceBusEnvironment.CreateServiceUri(
"sb",
"wcfonazure",
"secretservice")));
cf.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior
{
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(
"owner",
"D1Kmb83CCLrAtz4du9vb3xn99DaM2dH4jQqSec98if4=")
});
using (var ch = cf.CreateChannel())
{
Console.WriteLine(ch.GetSecretData(42));
}
Console.ReadLine();

You use the same service interface that you use on the host. By making sure that you
use the correct namespace and default key, you can create a channel to the relay and send
a message. The relay takes your message and passes it to the hosting service that can run
anywhere.



Objective 3.7: Create and configure a WCF service on Windows Azure

CHAPTER 3

253

Thought experiment
Talking with your customer
In this thought experiment, apply what you’ve learned about this objective. You can
find answers to these questions in the “Answers” section at the end of this chapter.
You are consulting for a customer that is thinking about how to expose his private
and confidential data to employees who work remotely. The customer is currently
hosting his data in his own datacenter. Currently, employees can synchronize a copy
of their data only when they are at the office.
With this in mind, answer the following questions:

1. Would you recommend the customer use a cloud or for a hybrid solution? Why?
2. How can the relaying capabilities of the service bus help your customer?

Objective summary
■■

■■

■■

■■

■■

Azure Service Bus helps you create hybrid applications that span the cloud and onpremise datacenters.
When working with service bus relay, you need to install the NuGet Package WindowsAzure.ServiceBus into your projects.
You can host your WCF service on premise. By adding extra bindings that are specifically created for the service bus, you can expose your application securely through
firewalls.
You need to create a service bus with a unique namespace on Azure to relay your
messages.
Client applications can connect to the service bus without knowing where the actual
service is hosted. The relaying service authenticates clients and forwards messages to
the on-premise service.

Objective review
Answer the following questions to test your knowledge of the information in this objective.
You can find the answers to these questions and explanations of why each answer choice is
correct or incorrect in the “Answers” section at the end of this chapter.

254

CHAPTER 3

Designing and implementing WCF Services

1. Which elements do you need from the management portal when configuring your

host service? (Choose all that apply.)
A. Namespace
B. NetTcpRelayBinding
C. ServiceHost
D. Default Key
2. You want to use a SharedSecretToken for authentication. Which method and param-

eters do you use?
A. TokenProvider.CreateSharedSecretTokenProvider(namespace, key)
B. TokenProvider.CreateSamlTokenProvider(samltoken)
C. TokenProvider.CreateSharedSecretTokenProvider(owner, key)
D. TokenProvider.CreateWindowsTokenProvider(uris)
3. You want to connect a client to the service bus. Which elements do you need? (Choose

all that apply.)
A. Namespace
B. Service path
C. Owner name
D. Default Key

Objective 3.8: Implement messaging patterns
Message exchange patterns (MEPs) are mechanisms that describe how the client and the
server should exchange data. There are three primary MEPs to choose from: datagram,
request-response, and duplex.

This objective covers how to:
■■

Implement one-way, request/reply, streaming, and duplex communication

■■

Implement Windows Azure Service Bus and Windows Azure Queues

WCF provides communication patterns, so if you’re familiar with these concepts in any other
version or technology, they will be familiar to you.



Objective 3.8: Implement messaging patterns

CHAPTER 3

255

Implementing one-way, request/reply, streaming, and
duplex communication
Normally, you will call a service’s operation and wait for a response. The response might indicate that nothing happened, but it still indicates that the operation completed successfully or
an exception was encountered. There are times, (for example with logging), though, when you
want to implement so-called fire and forget operations (meaning you call the method, and
if an exception is encountered, you don’t care or choose to do anything as a result). Fire and
forget functionality is implemented in WCF by using the OneWay attribute.
You can define an operation as one way with the IsOneWay parameter in the
OperationContract. Here is a quick illustration:
[OperationContract(IsOneWay = true)]
void LogMessage(String messsage);

First, to designate an operation as one way, you set the IsOneWay parameter to True. Second, you can’t have a return type defined (which should become clear momentarily). So that’s
the how; here’s everything else.
Although few people make a point of memorizing all the current http response codes,
chances are you’ve consciously come across several of them over the years and come across
them all the time when working with the web whether or not you realize it.
A request is made to the server, and the server sends back a response. Marking something
as OneWay essentially does a pass-fake on the process. It sends back a HttpStatusCode of 202
(if you’re wondering, 202 simply echoes back “Accepted”). This code comes back immediately
before any processing begins. Here’s where things get tricky. Normally, you just get a 202,
and that’s the end of the story. But you might have a long-running procedure that’s marked
as OneWay. You get back an immediate 202, but the service is still holding on to and processing your request. Additionally, just because a response is issued doesn’t mean the client has it
or has accepted it. So it blocks until that response is received and accepted from the service.
This can cause problems when multiple requests are made on OneWay methods when using a
binding that is configured to use sessions.
Assume that you just called LongRunningMethodThatTakesForever and then called a
OneWay method right afterward. You would expect (well, hopefully not after reading this
chapter) that the immediate return of the OneWay response would get sent back to the
service, and another method could be called on that binding/session. But that’s not what will
happen. The first request will block the second unless it was specifically called in an asynchronous manner. The 202 response won’t be sent back for a long time, at least until after LongRunningMethodThatTakesForever completes, plus a little extra overhead for good measure.

256

CHAPTER 3

Designing and implementing WCF Services

MORE INFO  LIST OF HTTP STATUS CODES

You might find yourself running short on parlor tricks at your next happy hour. Nothing
impresses friends more than arcane trivia and semiuseless talents such as reading Hex on
the fly or having all the Http status codes memorized. On a serious note, however, if you’ve
never done so before, it wouldn’t hurt to spend just a minute or two and look over the current list of Http status codes available at http://www.w3.org/Protocols/HTTP/HTRESP.html.

This is one feature that is overused and misused more than just about anything else. The
only saving grace is that, even if it had counterparts since the early days of .asmx web services, it’s still obscure. The allure of fire and forget functionality makes many developers believe
it absolves them of exception handling, callbacks, and all sorts of other things that you have
to wait for to get back from the server. In a purely pedantic sense, that’s true. But it’s true in
the same way as closing your eyes absolves you of having to worry about traffic in front of
you as you drive. Sure, you don’t have to worry about everyone else, but you’re going to have
to deal with the consequences if you don’t.
So what makes a good candidate for a OneWay call? Mainly, it’s something you want to be
able to execute and forget about. If it doesn’t finish or complete correctly, there’s little to be
concerned about. Logging messages, for example, wouldn’t be horrendous consequences in
most instances if it didn’t get through or wasn’t processed correctly. So mainly low-priority,
low-importance utility tasks lend themselves to the use of the OneWay attribute. As you
can imagine, OneWay methods must not return any value and be typed as void or nothing
because one way calls don’t return anything other than a status code.

Streaming and duplex
Streaming data and implementing duplex communication (two-way) are likely exam candidates. When implementing streaming in WCF, you have two modes you can work with:
■■

Buffered

■■

Streaming

The default is the buffered transfer mode, which means that it must be completely assembled and received before the receiver can start reading or using it. In the streaming mode,
the receiver can begin to read the information as soon as it begins transmission and before
it’s been completely delivered. Not all data can be processed serially, so unless you can do
so, streaming won’t provide much value. However, particularly in cases where you are dealing with large file sizes (think audio or video files), streaming can be such a big factor that it
literally causes people to use or not use your application. If you don’t believe me, ask anyone
old enough to have been around on the Internet back in the early ‘90s when streaming media
was little more than a pipe dream. More than one person wasted several hours downloading
something, only to find out it was not what they wanted or worse.



Objective 3.8: Implement messaging patterns

CHAPTER 3

257

IMPORTANT  MAXRECEIVEDMESSAGESIZE

There are several values you can manipulate to control throughput that were discussed
previously, but one setting you frequently have to tweak is the maxReceivedMessageSize
value. If you are dealing with a method that passes back a string and accepts an integer as
an input parameter, you won’t run into any problems.

What about filling a collection or a dataset (which is a collection, but logically a little
different)? How many rows will you get back? What is the size of each row? What if you get
one more record than the threshold? Well, you’ll have a problem. This feature was enabled
as a security feature to preempt bad actors from flooding a server with large size payloads
and distributed denial-of-service (DDoS) attacks. However let’s say you bump the setting one
order of magnitude and then the database grows and you run into the problem again. So
you repeat it. And the process repeats itself. Usually by the second or third time, someone
in management says, “Enough of this. I don’t want this again. Turn the setting the whole way
up,” and that ends up being the default setting, which completely defeats the purpose for the
value in the first place.
It is not an exaggeration to say that sidestepping the value altogether by using the MaxValue of long (which is syntactical sugar for System.Int64) is common. Just for the record,
MaxValue equates to 9,223,372,036,854,775,807 bytes, which is quite large. The answer
isn’t to just keep increasing it; it is to keep your payload and message sizes tight and under
control. Those numbers can be calculated and should be, and you should have a good idea of
what capacity a setting can handle. Turning it the whole way up is the exact opposite idea of
least privilege: it’s like “most privilege,” which is ill-advised from a security point of view.
At the contract level, you start the process by defining the return type of a method as
a Stream. Next, you need to configure the binding, through code or configuration setting,
the TransferMode enumeration value to Streamed. Then you typically want to set the maxReceivedMessageSize to a value that’s the largest value you calculate to need for items you
stream. This is a great candidate for one of those drag-and-drop exam items, and I’m guessing that, even if it’s not in the exam current version, it will make its way into a future version.

transferMode="Streamed"/>




maxReceivedMessageSize="67108864"/>



There are actually four different values available for the TransferMode enumeration according to MSDN, which are listed in Table 3-8.

258

CHAPTER 3

Designing and implementing WCF Services

TABLE 3-8  TransferMode enumeration values

Member name

Description

Buffered

The request and response messages are both buffered.

Streamed

Both the request and response are streamed.

StreamedRequest

The request message is streamed, and the response message is
buffered.

StreamedResponse

The request message is buffered, and the response message is
streamed.

There are a few other points to keep in mind. First, enabling streaming (versus buffering)
can improve scalability and responsiveness of a service by eliminating the need for large
memory buffers. However, just because you set the TransferMode to one of the Streamed
mechanisms, you can’t just assume that it will automatically fix all that ails you in terms of
performance or scalability. You have to keep in mind what’s better about it to understand
this. If the contents of what you are moving are so small that they easily fit into a buffer, you
won’t likely see a benefit. If you’re dealing with a large object (a Binary Large Object [BLOB],
for example) that can span several buffers, you’ll likely see a discernible improvement. This is
a great feature, but has the same sort of aura that indexes do—those who don’t know better
automatically suggest that it fix any performance problems in the same way they recommend
adding an index to a SQL table because things are running slowly. Like indexes, they can be a
great tool when used correctly, but they need to be used in the correct context for the right
reasons, and you should have the right expectations about them.
Along those same lines, not all bindings support TransferMode. The following out-ofthe-box bindings do support TransferMode and streaming. Keep in mind that this is not the
definitive list because you can create custom bindings specifically for this purpose:
■■

BasicHttpBinding

■■

NetTcpBinding

■■

NetNamedPipeBinding

Finally, note the following limitations and restrictions on using streaming:
■■

■■

■■



Operations that use a streamed transport can have a contract with only one input and
one output parameter.
SOAP headers are always buffered, even if you enable streaming. The headers for the
message must not exceed the size of the MaxBufferSize setting.
Reliable messaging and SOAP message-level security implementations rely on buffering messages for transmission. The overhead you incur by securing the channel can
easily offset any benefit you received from streaming. Generally, you should look to

Objective 3.8: Implement messaging patterns

CHAPTER 3

259

use transport-level security exclusively or mixed-mode security, which simply combines
WS-Security claims with transport-level security, making them similar to each other.

Request/reply
The request/reply pattern is technically mentioned as a possibility, but it’s something you
shouldn’t spend too much time studying. In just about every scenario you use in WCF, you’re
using the request/reply pattern, so you’re familiar with it if you’ve made any WCF calls or
written any services, even if you weren’t aware of it. The client initiates a request, and the
server receives it and processes it, and then commences with a reply. Every one of the TestService methods I initially created used this pattern. Request/Reply is the default way you use
client-initiated communication, and if you’re initiating a request from the client and not using
OneWay, you’re using it. Said differently, request/reply and OneWay are the only two patterns
that have to be initiated by the client. Everything covered so far, other than the OneWay examples, have been using this pattern, so there’s not a whole lot to talk about. And other than
knowing it must be initiated by the client, there’s not a lot more to know that hasn’t already
been discussed at length.

Duplex
The duplex pattern is much more complex than its counterparts and is not just a nicety; in
many cases, it’s an absolute necessity. Duplex messaging differs from its siblings in that it enables each established endpoint to send messages to any other endpoint by itself. As MSDN
states, “Duplex communication occurs when a client connects to a service and provides the
service with a channel on which the service can send messages back to the client.” In order for
this to happen, all the communication must occur within the context of one session.
Regardless of whether duplexing is being implemented, a WCF Service needs a contract,
and the contract requirement is handled by using an interface and the ServiceContract attribute. When using duplexing, an additional interface is required. This necessity entails a
callback contract, and this contract must be specified in the service contract by way of the
CallbackContract property.

Implementing Windows Azure service bus and Windows
Azure queues
A service bus is a component that helps you to connect applications. This could be a connection between on-premise and the cloud or between multiple applications running in the
cloud. As you have seen in the previous objective, the service bus relay is one option to connect applications.
However, using a relay is not suitable for all application types. Maybe you want to use a
simple queue, possibly extended with a publish/subscribe mechanism. Azure offers all those
different communication styles.

260

CHAPTER 3

Designing and implementing WCF Services