Windows Azure Service Bus Reference PDF
Windows Azure Service Bus Reference PDF
vice Bus
B
Refferen
nce
Seth Manhei
M m and Ralph
R Squillace
e
Categorry: Referencce
Applies to: Window
ws Azure Se
ervice Bus
Source: MSDN Librrary (link to
o source con
ntent)
E-book publicatio
on date: Ma
ay 2012
260 pages
The example companies, organizations, products, domain names, email addresses, logos, people, places, and events
depicted herein are fictitious. No association with any real company, organization, product, domain name, email address,
logo, person, place, or event is intended or should be inferred.
This book expresses the author’s views and opinions. The information contained in this book is provided without any
express, statutory, or implied warranties. Neither the authors, Microsoft Corporation, nor its resellers, or distributors will
be held liable for any damages caused or alleged to be caused either directly or indirectly by this book.
Contents
Service Bus .................................................................................................................................2
Release Notes for the Service Bus November 2011 Release ..................................................... 10
Best Practices for Performance Improvements Using Service Bus Brokered Messaging .......... 247
Note
To use the Service Bus features, install the Windows Azure SDK from the SDK download
page.
Use the following links to learn more about the Service Bus. These links come from various
content providers across Microsoft. This page will be updated periodically when new content is
available, so check back often to see what’s new.
3
In this section
About the Windows Azure Service Bus
Provides a conceptual introduction to the Service Bus.
4
of SOAP and REST-based clients. It also contains an overview of the new Service Bus
“brokered” messaging features, including Queues, Topics, and Subscriptions. This
overview discusses the differences between the original “relayed” and the new brokered
messaging patterns.
Troubleshooting
Describes common problems building applications that use the Service Bus and
solutions that may address those situations.
RelayConfigurationInstaller.exe Tool
Describes the usage of this tool, which adds the necessary configuration information to
the machine or application configuration file.
5
NAT router. It provides direct one-way or request/response (relayed) messaging as well as
brokered, or asynchronous, messaging patterns.
• The Access Control Service is an interoperable, claims-based service that provides
federated authentication and authorization solutions for any resource, whether in the cloud,
behind a firewall, or on a smart device.
• The Windows Azure Caching Service provides a distributed, in-memory cache that helps
Windows Azure applications to achieve increased performance and scalability.
The Service Bus and Access Control together make hybrid, connected applications—applications
that communicate from behind firewalls, across the Internet, from hosted cloud servers, between
rich desktops and smart devices—easier to build, secure, and manage. Although you can build
hybrid, connected applications today, doing this often means you have to build important
infrastructure components before you can build the applications themselves. The Service Bus
and Access Control provide several important infrastructure elements so that you can more easily
begin making your connected applications work now.
6
• As ubiquitous as Web browsers are, their reach into data is limited to an interactive exchange
in a format they understand.
• Heterogeneous platforms, such as server applications, desktop or portable computers, smart
devices, and advanced cell phones, often interoperate at a rudimentary level, if at all. They
can rarely share the same code base or benefit from feature or component reuse.
• Much of the most valuable data is stored in servers and embedded in applications that will
not be replaced immediately—sometimes referred to as “legacy” systems. The data in these
systems are trapped by technical limitations, security concerns, or privacy restrictions.
• The Internet is not always the network being used. Private networks are an important part of
the application environment, and their insulation from the Internet is a simple fact of
information technology (IT) life.
Service Bus and Access Control are built to overcome these kinds of obstacles; they provide the
“fabric” that you can use to build, deploy, and manage the distributed applications that can help
make the promise of “Software + Services” become real. The Service Bus and Access Control
services together are highly-scalable services that are running in Microsoft data centers that can
be used by applications anywhere to securely bridge the gap between local applications behind a
firewall, applications that are running in the cloud, and client applications of any kind around the
world. Another way of saying this is that the Service Bus and Access Control are the glue that
makes “Software” and “Services” work together.
Feature Overview
The Service Bus connects local, firewalled applications and data with applications in the cloud,
rich desktop applications, and smart, Web-enabled devices anywhere in the world.
Access Control Service is a claims-based access control service that can be used on most
Web-enabled devices to build interoperable, federated authentication and authorization into any
connected application. The following diagram illustrates this architecture.
7
The Windows Azure Caching Service provides a distributed, in-memory cache that helps
Windows Azure applications to achieve increased performance and scalability.
8
Access Control Features
The Access Control service provides claims-based authentication and authorization for REST
Web services.
• Usable from any platform.
• Low friction way to onboard new clients.
• Integrates with AD FS v2.
• Implements OAuth Web Resource Authorization Protocol (WRAP)and Simple Web Tokens
(SWT).
• Enables simple delegation.
• Trusted as an identity provider by the Service Bus.
• Extensible to provide integration with any identity provider.
Caching Features
Windows Azure Caching enables applications to cache activity and reference data for .NET
applications running in Windows Azure. This includes the following features.
• Usable from any .NET application hosted in Windows Azure.
• Provides automatic management of the caching infrastructure in the cloud.
• Provides ASP.NET session state and output caching providers.
• Configurable through application configuration files or programmatically.
• Provides a API centered around cache access with key-value pairs.
• Usable with optimistic or pessimistic concurrency.
• Supports the local cache feature for additional performance and scalability benefits.
9
Release Notes for the Service Bus November
2011 Release
Note
The Service Bus components are now included with the “Windows Azure Libraries for
.NET.” To install, visit the Windows Azure SDK download page.
The release notes for the Windows Azure Service Bus November 2011 release contain the
following topics:
1. Prerequisites
2. What’s New
3. Changes
4. Known Issues
These release notes will be updated periodically. For the latest update, please click here.
See the Service Bus and Pricing FAQ topic for a list of Service Bus FAQs.
Prerequisites
Account Requirements
Before running Windows Azure Service Bus applications, you must create one or more service
namespaces. To create and manage your service namespaces, log on to the Windows Azure
Management portal, click Service Bus, Access Control & Caching, then click Service Bus. In
the left-hand tree, click the service namespace you want to manage. For more information,
see Managing Service Bus Service Namespaces.
SDK Samples
Note
By default, the Service Bus samples are no longer installed with the SDK. To obtain the
samples, visit the Windows Azure SDK samples page.
Most SDK samples and applications contain three authentication requirements:
1. Service Namespace: You can use the service namespace you created in your project on the
portal. The service namespace is used to construct Service Bus endpoints (for example,
sb://<domain>.servicebus.windows.net/Echo/)
2. Issuer Name: You can use owner, which is an issuer that is created by default for you.
3. Issuer Key/Secret: You can use the Default Issuer Key option listed on the Service
Namespace management page on the portal.
10
Runtime Requirements
The November 2011 release of the Service Bus includes reliable, or “brokered’ messaging
enhancements and is commercially available today. This release is fully backward compatible
and you can continue to use your existing applications. Windows Azure Access Control Service
(ACS) integration has been updated from ACS v1 to ACS v2. You can obtain updated client
assemblies for these features by installing the Windows Azure SDK version 1.6.
The .NET Framework managed APIs for accessing all Service Bus functionality including the
existing relayed messaging and new brokered messaging features are included in a single
assembly: Microsoft.ServiceBus.dll (version 1.6.0.0). This assembly targets the .NET Framework
version 4 and is backward compatible with both Microsoft.ServiceBus.dll v1.0.0.0 and v1.5.0.0.
Note
The Service Bus assemblies are no longer installed in the .NET Global Assembly Cache
(GAC) by default. The updated default locations for these assemblies are:
• Service Bus assemblies: C:\Program Files\Windows Azure SDK\v1.6\ServiceBus\ref.
• Service Bus tools (RelayConfigurationInstaller.exe): C:\Program Files\Windows Azure
SDK\v1.6\ ServiceBus\bin.
Any existing applications that target the .NET Framework 3.5 can continue to use
Microsoft.ServiceBus.dll (version 1.0.0.0), which includes the previously shipped relayed
messaging APIs and QFE fixes.
There are three versions of the SDK now available:
• Windows Azure SDK version 1.6: Includes Microsoft.ServiceBus.dll version 1.6.0.0, which is
an updated version of Microsoft.ServiceBus.dll version 1.5.0.0 that includes all the same
brokered and relayed messaging features. Previously these assemblies shipped as part of
the Windows Azure AppFabric SDK.
• Windows Azure AppFabric SDK version 1.5: Includes Microsoft.ServiceBus.dll version
1.5.0.0, which first introduced the new Service Bus Topics and Queues brokered messaging
features (and includes the existing relayed messaging features), and updated Caching client
assemblies. This SDK is targeted at the .NET Framework 4.
• Windows Azure AppFabric SDK version 1.0: Includes Microsoft.ServiceBus.dll version
1.0.0.0, which contains only the existing relayed messaging features and targets the .NET
Framework 3.5.
Note
Installing the current Windows Azure 1.6 SDK does not uninstall the 1.0 Windows Azure
SDK. You must uninstall it manually.
The Windows Azure SDK samples are available as Visual Studio 2010 solutions (C# and Visual
Basic), and require either Microsoft .NET Framework 3.5 SP1 or .NET Framework 4 to run. The
SDK is supported on the Windows Server 2008, Windows°7, Windows Vista, Windows Server
2003, and Windows XP operating systems. Additionally, some of the samples require the
Windows Azure SDK version 1.6 and Windows Azure tools for Visual Studio version 1.6.
Windows Identity Foundation (WIF) is required for Active Directory Federation Services V2
(ADFS) integration. For WIF system requirements, click here.
11
Note
If a sample has both a service and a client application, please use the credentials from
the same service namespace in the both the service and the client.
What’s New
Note
If you exceed the limit of 25 concurrent listeners, you will receive a
System.ServiceModel.QuotaExceededException exception.
• Support for ports in messaging operations: you must now explicitly set the
Microsoft.ServiceBus.ConnectivityMode enumeration to
Microsoft.ServiceBus.ConnectivityMode.Http, in order to get messaging operations to use
12
port 80/443. Using the Microsoft.ServiceBus.ConnectivityMode.AutoDetect mode does
not achieve this result.
Changes
This section lists important changes in the Service Bus November 2011 release.
• There is no longer a separate SDK installer for the Windows Azure SDK. The Service Bus
and cache components are now included with the “Windows Azure Libraries for .NET.” To
install, visit the Windows Azure SDK download page.
• The Service Bus and cache assemblies are no longer installed in the .NET Global Assembly
Cache (GAC) by default. The updated default locations for these assemblies are:
• cache assemblies: C:\Program Files\Windows Azure SDK\v1.6\Cache\ref.
• Service Bus assemblies: C:\Program Files\Windows Azure SDK\v1.6\ServiceBus\ref.
• Service Bus tools (RelayConfigurationInstaller.exe): C:\Program Files\Windows Azure
SDK\v1.6\ ServiceBus\bin.
• The current Message Buffers feature, including their management protocol, will remain
supported for backwards compatibility. However, the general recommendation is that you
explicitly change client code to use the new Service Bus Queues feature. For more
information, see Queues, Topics, and Subscriptions.
• The Service Bus no longer adds entries to the Machine.config file. When running code
developed with previous versions of the Windows Azure SDK, you may see errors such as
the following:
Configuration binding extension
'system.serviceModel/bindings/netTcpRelayBinding' could not be found. Verify
that this binding extension is properly registered in
system.serviceModel/extensions/bindingExtensions and that it is spelled
correctly.
It is recommended that you add these extensions to the App.config files for your projects or
use the Relayconfiginstaller.exe tool in the SDK to add these bindings. For example:
<configuration>
<system.serviceModel>
<extensions>
<!-- Adding all known service bus extensions. You can remove the
ones you don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior"
type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement
, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
13
<add name="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpoint
BehaviorElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="serviceRegistrySettings"
type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettings
Element, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingT
ransportExtensionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="tcpRelayTransport"
type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElemen
t, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="httpRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpRelayTransportEleme
nt, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="httpsRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElem
ent, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="onewayRelayTransport"
type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportE
lement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCo
llectionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="webHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingColl
14
ectionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ws2007HttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingC
ollectionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingColle
ctionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netOnewayRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCo
llectionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netEventRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCol
lectionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netMessagingBinding"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingB
indingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
</system.serviceModel>
</configuration>
• If you perform management operations using the Access Control version 1.0 Acm.exe tool,
this tool is no longer shipped with the version Windows Azure 1.6 SDK. If you require access
to this tool, you will have to roll back to the Windows Azure version 1.0 SDK.
Known Issues
The following section lists known issues in this release of the Service Bus:
• After installing the Windows Azure 1.6 SDK, any application that uses the Machine.config file
may encounter the following error:
Exception type:
System.Configuration.ConfigurationErrorsException
Message: Configuration binding extension
'system.serviceModel/bindings/netTcpRelayBinding' could not be
15
found. Verify that this binding extension is properly registered
in system.serviceModel/extensions/bindingExtensions and that it
is spelled correctly.
InnerException: <none>
StackTrace (generated):
SP IP Function
0F1DE230 5F22EA4C
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.EvaluateOne(System.String[],
System.Configuration.SectionInput, Boolean,
System.Configuration.FactoryRecord,
System.Configuration.SectionRecord, System.Object)+0xc8
0F1DE30C 5F22E86E
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.Evaluate(System.Configuration.FactoryRecord,
System.Configuration.SectionRecord, System.Object, Boolean,
Boolean, System.Object ByRef, System.Object ByRef)+0x482
0F1DE3CC 5F226F8D
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.GetSectionRecursive(System.String, Boolean, Boolean,
Boolean, Boolean, System.Object ByRef, System.Object
ByRef)+0x5bd
0F1DE454 5F226F8D
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.GetSectionRecursive(System.String, Boolean, Boolean,
Boolean, Boolean, System.Object ByRef, System.Object
ByRef)+0x5bd
0F1DE4DC 5F226F8D
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.GetSectionRecursive(System.String, Boolean, Boolean,
Boolean, Boolean, System.Object ByRef, System.Object
ByRef)+0x5bd
0F1DE564 5F226F8D
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.GetSectionRecursive(System.String, Boolean, Boolean,
Boolean, Boolean, System.Object ByRef, System.Object
ByRef)+0x5bd
16
0F1DE5EC 5F2269BA
System_Configuration_ni!System.Configuration.BaseConfigurationRe
cord.GetSection(System.String)+0x2a
0F1DE5FC 5F22A7D5
System_Configuration_ni!System.Configuration.ClientConfiguration
System.System.Configuration.Internal.IInternalConfigSystem.GetSe
ction(System.String)+0x55
0F1DE610 5F2210EF
System_Configuration_ni!System.Configuration.ConfigurationManage
r.GetSection(System.String)+0x4f
This is caused by a known issue in the upgrade from the Windows Azure 1.0 SDK to the
Windows Azure 1.6 SDK. The following workaround resolves the issue:
a. Uninstall the Windows Azure SDK version 1.6.
b. Install the Windows Azure SDK version 1.0
from http://go.microsoft.com/fwlink/?LinkID=228910. On the Add/Remove Programs
Control Panel applet, this appears as version 1.0.1471.
c. Reinstall the Windows Azure SDK version 1.6
from http://go.microsoft.com/fwlink/?LinkID=226941.
This will remove all Service Bus bindings from the Machine.config file. For more information,
see the second Service Bus bullet in the “Changes” section of these release notes.
• It is currently not possible to use the Windows Communication Foundation (WCF) Service
Model Metadata Tool (Svcutil.exe) to generate a proxy from a service that uses
Microsoft.ServiceBus.
• Microsoft.ServiceBus.BasicHttpRelayBinding limitation: The size of each individual
attribute value cannot exceed 16k. If it exceeds this threshold, an exception is generated
indicating that the MaxNameTableCharCount has been exceeded. The
MaxNameTableCharCount value of the ReaderQuotas property is set to the default value
of 16K, and this is the value which indicates the maximum size of each of the attribute values.
• Message Buffer characters: If you use certain non-alphanumeric characters in the name of a
message buffer, such as a question mark (encoded as %3F), or an equal sign (encoded as
%3D), you may experience an authorization failure
(RelayedHttpServiceAuthorizationFailure) and be unable to send messages to the buffer.
Be sure to use alphanumeric characters in your message buffer names.
• ProtocolException when closing a service while it is receiving multicast messages: When you
end a multicast service while it is still receiving messages, you may receive a
System.ServiceModel.ProtocolException with the message “Unhandled Exception:
System.ServiceModel.ProtocolException: The channel received an unexpected input
message …” The error will not interfere with the closing of the channel and can be safely
ignored.
• Listener recovery delay: Under rare hardware failure conditions, listeners constructed using
the Microsoft.ServiceBus.NetOnewayRelayBinding binding can require up to five minutes
17
to recover. During this period, an attempt to re-create a failed listener may be unsuccessful
and generate an AddressAlreadyInUseException message.
• When authenticating with SAML tokens, clients must send a new token to the Service Bus
before the SAML token expires. Doing so avoids an interruption in connectivity with the
Service Bus. Assign the new token to the same
Microsoft.ServiceBus.TransportClientEndpointBehavior behavior you used to establish
the original connection.
• In a Retrieve/Peeklock operation, a client may generate a
System.ServiceModel.FaultException (“Message could not be retrieved”) instead of a
System.TimeoutException (“Message could not be retrieved: NoContent, No message
available within the specified timeout.”). This may occur when the server closes the keepalive
connection if no request is received within 1 minute of the first request. To work around this
issue, set the retrieve time-out to a value less than 1 minute (for example, 55 seconds).
• Message Buffer expiration: When you create a message buffer, you can specify a time after
which the message buffer will expire if there are no requests to receive a message within that
time interval. The default is five minutes. When you request a message from the message
buffer, you can specify the number of seconds the request will wait for a message to arrive at
an empty buffer before the request times out. The default is one minute. When a request to
receive a message reaches a buffer, the expiration timer is reset and starts counting down
again. Therefore, if you specify a longer receive request time-out than the expiration time on
the buffer, and no messages are received, the buffer can actually expire while a receive
request is still pending. In that case, the buffer will disappear and the receive request throws
an exception. To avoid this behavior, accept the default message buffer settings, or make
sure that you specify an expiration interval for the buffer that is longer than the receive time-
out interval.
• Because of a bug in Windows Communication Foundation (WCF), when WCF activity tracing
is on, a call to Channel.Open when you are using the NetTcpRelayBinding binding
generates a NullReferenceException. This bug has been fixed in WCF 4.0.
• ATOM feed always comes back empty when a GET request is made against an HTTP URI
unless the Cache-Control max-age=0 header is set. A GET against HTTPS URIs works fine
without the need for this header.
• When using the Ws2007HttpRelayBinding binding protocol, a time-out can occur during
periods of moderate to high system load. Because of this behavior, we recommend that for
solutions requiring a high degree of reliability, you use the WebHttpRelayBinding binding
instead.
• The following operations will not work with Flash clients that are trying to use message buffer
in the Service Bus:
a. PeekLock
b. Unlock locked message
c. Delete locked message
• The following are known issues in the Windows Azure portal while managing Service Bus
entities:
• The maximum number of queues or topics that can be displayed per service namespace
is 25. The maximum number of displayed subscriptions per topic is 5. They are sorted
18
alphabetically. It is strongly recommended that you use the Service Bus managed APIs to
create or delete queues, topics, or subscriptions if you intend to manage more entities
than the current portal limitations.
• The topic length is always set to zero. However, the size of the topic reflects the number
of bytes currently occupied by messages still in the queue.
• The default timeout on the System.Net.ServicePointManager.MaxServicePointIdleTime
property (an Http library that maintains a pool of connections) is 100secs. The timeout for
Windows Azure server keepalive timeouts is 60 seconds. Therefore, if you have a connection
that is idle for more than 60 seconds, it is disconnected by Windows Azure, and the next time
you try to use the connection it returns an error. The workaround is to set the
System.Net.ServicePointManager.MaxServicePointIdleTime property to a value less than
the Windows Azure server keepalive timeout. This way, the connection is removed before
Windows Azure disconnects it
• If you are upgrading from the Windows Azure SDK version 1.0, you may see the following
behavior:
a. Warning messages due to obsolete classes:
'Microsoft.ServiceBus.TransportClientCredentialType' is obsolete
'Microsoft.ServiceBus.TransportClientEndpointBehavior.CredentialT
ype' is obsolete: '"This property is deprecated. Please use
TransportClientEndpointBehavior.TokenProvider instead."'
'Microsoft.ServiceBus.TransportClientEndpointBehavior.Credentials
' is obsolete: '"This property is deprecated. Please use
TransportClientEndpointBehavior.TokenProvider instead."'
'Microsoft.ServiceBus.TransportClientEndpointBehavior.Credentials
' is obsolete: '"This property is deprecated. Please use
TransportClientEndpointBehavior.TokenProvider instead."'
b. Exceptions when running your application due to missing entries in Machine.config
(please add entries to the App.config file, as described in the “Changes” section):
System.Configuration.ConfigurationErrorsException was unhandled
19
Quotas
For information about quotas for the Service Bus, see the Windows Azure Platform pricing FAQ.
20
• Does the Service Bus charge for storage?
• How much billable usage will I see if I operate 100 queues for 24 hours, each processing one
128 KB message per minute?
• How much billable usage will I see if I operate 1 topic with 4 subscriptions for 24 hours,
processing one 45 KB message per second?
• How much billable usage will I see if I operate 10 non-netTCP relays for 24 hours, each
processing one 8KB message per second?
• How much billable usage will I see if I operate 10 netTCP relays for 24 hours, each
processing one 8KB message per second?
• Does the Service Bus have any usage quotas?
What are the main capabilities and benefits of the Service Bus?
21
• Service Bus queues offer a reliable, highly scalable way to store messages as they travel
between systems without losing messages in the event of connectivity failure.
• Service Bus topics and subscriptions implement a publish/subscribe pattern that delivers a
highly scalable, flexible, and cost-effective way to publish messages from an application and
deliver them to multiple subscribers.
• The Service Bus relay enables applications hosted in Windows Azure to securely call back to
private cloud-based applications hosted in your own datacenter behind a firewall, and vice
versa. The relay service avoids the need to instantiate and set up a new connection on each
call and makes connectivity faster and more reliable. It also supports the ability to integrate
applications across existing NATs and firewalls. The relay service supports a variety of
different transport protocols and Web services standards, including REST, SOAP, and WS-*.
• Companies can use the Service Bus relay to expose just the information they want from their
private cloud environment, which creates an architecture more secure than opening up a
VPN. Enterprises can use a SOA-based architecture and expose just the services they want
to deliver from their on-premise data centers.
How will you charge for the Service Bus once the promotional period
ends?
At the end of the promotional period, these meters will be billed as follows:
1. Messages – Messages sent to or delivered by the Service Bus will be billed at $0.01 per
10,000 messages. Messages are charged based on the number of messages sent to, or
delivered by, the Service Bus during the billing month. This includes delivery of “null”
messages in response to receive requests against empty queues/subscriptions. Messages
over 64KB in size will be charged an additional message for each additional 64KB of data
(rounded up). This meter applies to relays as well as queues, topics, subscriptions, and
message buffers.
2. Relay Hours – This meter applies only when using the Service Bus relay capability. There is
no relay hour charge if you are only using Service Bus queues, topics/subscriptions, or
message buffers. Relay hours will be billed at $0.10 per 100 relay hours, and charged from
the time the relay is opened (the first listener connect on a given relay address) to the close
of the relay (the last listener disconnect from that relay address), and rounded up to the next
whole hour.
In addition to the prices noted above for the Service Bus, you will be charged for associated data
transfers for egress outside of the data center in which your application is provisioned. You can
find more details in the What usage of the Service Bus is subject to data transfer? What is not?
section below.
22
What usage of the Service Bus is subject to data transfer? What is not?
Any data transfer within a given Windows Azure sub-region is provided at no charge. Any data
transfer outside a sub-region is subject to egress charges at the rate of $0.15 per GB from the
North America and Europe regions, and $0.20 per GB from the Asia-Pacific region. Any inbound
data transfer is provided at no charge.
23
How is the Messages meter calculated for queues, topics/subscriptions,
and message buffers?
Each message sent to or delivered by the Service Bus counts as a billable message. This applies
to all Service Bus entity types, including queues, topics/subscriptions, message buffers, and
relays.
A message is defined as a unit of data which is 64KB or less in size. In the case of brokered
entities (queues, topics/subscriptions, message buffers), any message that is less than or equal
to 64KB in size is considered as one billable message. If the message is greater than 64KB in
size, the number of billable messages is calculated according to the message size in multiples of
64KB. For example, an 8 KB message sent to the Service Bus will be billed as one message, but
a 96 KB message sent to the Service Bus will be billed as two messages. In most cases, the
same method of determining billable messages is applicable to relays as well. See the How is the
Messages meter calculated for relays? section for details about the exception cases for relays.
Multiple deliveries of the same message (for example, message fan out to multiple listeners or
message retrieval after abandon, deferral, or dead lettering) will be counted as independent
messages. For example, in the case of a topic with three subscriptions, a single 64 KB message
sent and subsequently received will generate four billable messages (one “in” plus three “out”,
assuming all messages are delivered to all subscriptions).
In general, management operations and “control messages,” such as completes and deferrals,
are not counted as billable messages. There are two exceptions:
1. Null messages delivered by the Service Bus in response to requests against an empty
queue, subscription, or message buffer, are also billable. Thus, applications that poll against
Service Bus entities will effectively be charged one message per poll.
2. Setting and getting state on a MessageSession will also result in billable messages, using
the same message size-based calculation described above.
How much billable usage will I see if I operate 100 queues for 24 hours,
each processing one 128 KB message per minute?
• Assume all messages in each queue are delivered exactly once.
• 1 message of 128 KB = 2 billable messages (128 KB/64 KB).
• 2 billable messages sent per minute + 2 billable messages delivered per minute = 4 billable
messages per queue per minute.
• 4 messages per queue per minute * 1,440 minutes per day = 5,760 messages per queue per
day.
• Total billable messages per day sent to/delivered by the Service Bus = 5,760 messages per
queue per day * 100 queues = 576,000 messages per day.
• 576,000 Service Bus messages cost 576,000/10,000 * $0.01 = 58 * $0.01 = $0.58 per day.
How much billable usage will I see if I operate 1 topic with 4 subscriptions
for 24 hours, processing one 48 KB message per second?
• Assume all subscriptions receive all messages, and all messages in each subscription are
delivered exactly once.
25
• 1 message of 48 KB = 1 billable message.
• 1 billable message per second * 86,400 seconds per day = 86,400 billable messages per day
sent to the topic.
• 86,400 messages per day * 4 subscriptions = 345,600 messages per day delivered to
subscription clients.
• Total billable messages per day sent to/delivered by the Service Bus = 86,400 + 345,600 =
432,000 messages per day.
• 432,000 Service Bus messages cost 432,000/10,000 * $0.01 = 44 * $0.01 = $0.44 per day.
How much billable usage will I see if I operate 10 non-netTCP relays for 24
hours, each processing one 8KB message per second?
• Assume a request/reply pattern and all requests receive replies <= 64 KB in size.
• 1 message of 8 KB = 1 billable message.
• 1 billable message per second * 86,400 seconds per day = 86,400 billable messages per day
for request messages sent via each relay.
• Since all requests receive replies, also have 86,400 billable messages per day for reply
messages sent via each relay.
• Total billable messages per day per relay = 86,400 * 2 = 172,800.
• Total billable messages per day sent to/received by the Service Bus = 172,800 * 10 Relays =
1,728,000.
• 1,728,000 Service Bus messages cost 1,728,000/10,000 * $0.01 = 173 * $0.01 = $1.73.
• 10 relays open 24 hours = 240 relay hours.
• 240 relay hours cost 240/100 * $0.10 = 3 * $0.10 = $0.30.
• Total cost = $1.73 + $0.30 = $2.03 per day.
How much billable usage will I see if I operate 10 netTCP relays for 24
hours, each processing one 8KB message per second?
• Assume a request/reply pattern and all requests receive replies <= 64 KB in size.
• 8 KB per second * 3,600 seconds per hour = 28,800 KB per hour for request messages sent
via each relay.
• Since all requests receive replies, also have 28,800 KB per hour for reply messages sent via
each relay.
• Total message data per hour per relay = 57,600 KB.
• 57,600 KB = 57,600/64 or 900 billable messages per hour per relay = 900 * 24 or 21,600
billable messages per day per relay.
• Total billable messages per day sent to/received by the Service Bus = 21,600 messages * 10
relays = 216,000.
• 216,000 Service Bus messages cost 216,000/10,000 * $0.01 = 22 * $0.01 = $0.22.
• 10 relays open 24 hours = 240 relay hours.
• 240 relay hours cost 240/100 * $0.10 = 3 * $0.10 = $0.30.
26
• Total cost = $0.22 + $0.30 = $0.52 per day.
Requirements
The following topic describes the developer and system requirements for running a Windows
Azure application that uses the Service Bus.
Developer Requirements
In order to develop and run an Windows Azure application, you should have a basic level of
familiarity with either C# or Visual Basic .NET. You should also be familiar with the following
technologies:
• Service Bus
28
If you are developing an Service Bus basic service or client application, you should be
generally familiar with the Windows Communication Foundation (WCF) programming
framework. It is possible to use this documentation without knowing WCF programming.
However, many of the topics here reference WCF as a source of additional information, or
use the WCF documentation as a base from which to expand.
• Windows Azure and Service Bus
Creating a Windows Azure application that uses the Service Bus is very similar to a basic
Service Bus application: the main additions are mainly around configuration and setup.
Therefore, you should be generally familiar with the Windows Azure programming
environment, so that you can reasonably create a basic Windows Azure application.
• REST and the Service Bus
As with Windows Azure, creating a REST-based service or client application is very similar to
the basic Service Bus programming model: other than the choice of bindings and some
tagging, the actual differences are relatively minor. Therefore, you should be generally
familiar with the REST protocol and Web programming. If you want to use the message
buffer feature to create a purely HTTP-based application (for example, one that does not use
the Service Bus and the Service Bus service), you should be much more experienced with
the Web programming and messaging models.
System Requirements
In order to run an Service Bus client or service application, you must have the following:
• Windows XP Service Pack 3 or higher, Windows Vista, Windows Server 2008, Windows
Server 2008 R2, or Windows°7.
• .NET Framework 3.5, Service Pack 1.
• Windows Azure SDK.
• HTTP/S connectivity to the Internet.
• To use TCP connectivity, your computer must be able to open outbound connections to the
Service Bus using ports 808 and 828.
• To establish direct connections to clients (hybrid mode), your computer must be able to
connect to the Service Bus using port 819.
For more information about port settings, see Service Bus Port Settings.
In This Section
How to: Create or Modify a Service Bus Service Namespace
29
How to: Delete a Service Bus Service Namespace
Note
You do not have to use the same service namespace for both client and service
applications.
6. Click Check Availability. This will check that the name that you selected for your service
namespace is valid and available. If it is not, you can enter a different name.
7. Choose a region and in the available dropdown. Then click OK.
8. The system now creates your service namespace and enables it.
You might have to wait several minutes as the system provisions resources for your
account.
30
add or remove the services for which this namespace is valid. You can only customize
the service properties for services being added. At this time you cannot modify the
properties of service namespaces for existing services.
3. Note that if you clear the checkboxes for all services in the Available Services pane, the
service namespace is deleted.
4. When you are finished, click Modify Namespace to commit the changes and close the
Modify a Service Namespace dialog.
General Quotas
The maximum number of service namespaces allowed per Windows Azure account is 50.
For information about other quotas for the Windows Azure Service Bus, see the Windows Azure
Platform pricing FAQ.
Messaging Quotas
The following table lists quota information specific to the Service Bus:
31
Quota Name Scope Type Behavior when exceeded Value
Message size for System- Static Incoming messages that exceed these Maximum
a wide quotas will be rejected and an message
queue/topic/subsc exception will be received by the calling size: 256KB
ription entity code. Maximum
header size:
64KB
Maximum
number of
header
properties in
property bag:
32
Quota Name Scope Type Behavior when exceeded Value
MaxValue
Maximum
size of
property in
property bag:
No explicit
limit. Limited
by maximum
header size.
Message size for System- Static Incoming messages that exceed these 64KB
Message Buffer wide quotas will be rejected and an
exception will be received by the calling
code.
Message size for System- Static Incoming messages that exceed these 64KB
Microsoft.Servic wide quotas will be rejected and an
eBus.NetOnewa exception will be received by the calling
yRelayBinding code.
and
Microsoft.Servic
eBus.NetEventR
elayBinding
relays
33
Quota Name Scope Type Behavior when exceeded Value
cannot
exceed 64K.
This applies
to the entire
header of the
Microsoft.Se
rviceBus.Me
ssaging.Bro
keredMessa
ge, which has
both user
properties as
well as
system
properties
(such as
Microsoft.Se
rviceBus.Me
ssaging.Bro
keredMessa
ge.Sequence
Number,
Microsoft.Se
rviceBus.Me
ssaging.Bro
keredMessa
ge.Label,
Microsoft.Se
rviceBus.Me
ssaging.Bro
keredMessa
ge.MessageI
d, and so on).
34
Quota Name Scope Type Behavior when exceeded Value
35
The Service Bus Message Buffer Tutorial topics show how to securely use REST message
exchanges to register a REST endpoint with the Service Bus and build a REST client that
communicates with the REST service through the Service Bus endpoint. This tutorial
demonstrates one programming approach, by using the WCF Web HTTP Programming Model
to create a service application that registers an HTTP/GET endpoint securely through the Service
Bus, by using the standard WCF bindings that are available with Windows Azure. The client can
then use any Web browser to start the service by using the URL of the Service Bus endpoint.
You can of course also use REST-style communication to register a REST endpoint with the
Service Bus, although the REST tutorial does not demonstrate this.
In This Section
Service Bus Relayed Messaging Tutorial
Includes topics that describe how to build a simple Service Bus client application and
service.
36
main difference between a WCF and an Service Bus service is that the endpoint is exposed in the
cloud instead of locally on your computer.
After you work through the sequence of topics in this tutorial, you will have a running service, and
a client that can invoke the operations of the service. The first topic describes how to set up an
account. The next three topics describe how to define a service that uses a contract, how to
implement the service, and how to configure the service in code. They also describe how to host
and run the service. The service that is created is self-hosted and the client and service run on
the same computer. You can configure the service by using either code or a configuration file. For
more information, see Configuring a WCF Service to Register with the Service Bus and Building a
Service for the Service Bus.
The next three topics describe how to create a client application, configure the client application,
and create and use a client that can access the functionality of the host. For more information,
see Building a Service Bus Client Application and Discovering and Exposing a Service Bus
Service.
All of the topics in this section assume that you are using Visual Studio 2010 as the development
environment. If you are using another development environment, ignore the Visual Studio-specific
instructions.
For more in-depth information about how to create Service Bus client applications and hosts, see
the Developing Applications that Use the Service Bus section.
In This Section
Step 1: Sign up for an Account
Step 2: Define a WCF Service Contract to use with Service Bus
Step 3: Implement the WCF Contract to use Service Bus
Step 4: Host and Run a Basic Web Service to Register with Service Bus
Step 5: Create a WCF Client for the Service Contract
Step 6: Configure the WCF Client
Step 7: Implement WCF Client to Call the Service Bus
See Also
Service Bus Brokered Messaging .NET Tutorial
37
through the Service Bus. A shared secret key is automatically generated by the system when a
service namespace is created. The combination of service namespace and shared secret key
provides a credential for the Service Bus to authenticate access to an application.
Expected time to complete: 5 minutes
Note
You do not have to use the same service namespace for both client and service
applications.
38
EchoService. Use the default Location. Click OK to create the project.
3. Note that the following two steps (4 and 5) are not necessary if you are running Visual
Studio 2008.
4. In the Solution Explorer, right-click the name of your project (in this example,
EchoService), and click Properties.
5. Click the Application tab on the left, then select .NET Framework 4 from the Target
framework: dropdown. Click Yes when prompted to reload the project.
6. For a C# project, Visual Studio creates a file that is named Program.cs. This class will
contain an empty method called Main(). This method is required for a console application
project to build correctly. Therefore, you can safely leave it in the project.
7. Add a reference to System.ServiceModel.dll to the project:
a. In the Solution Explorer, right-click the References folder under the project folder
and then click Add Reference….
b. Select the .NET tab in the Add Reference dialog and scroll down until you see
System.ServiceModel, select it, and then click OK.
39
Note
When using a command-line compiler (for example, Csc.exe), you must also
provide the path of the assemblies. By default, for example on a computer that is
running Windows°7, the path is:
Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation.
8. In the Solution Explorer, double-click the Program.cs file to open it in the editor.
9. Add a using statement for the System.ServiceModel namespace.
using System.ServiceModel;
System.ServiceModel is the namespace that lets you programmatically access the
basic features of WCF. Service Bus uses many of the objects and attributes of WCF to
define service contracts. You will most likely use this namespace in most of your Service
Bus applications.
10. Change the namespace name from its default name of EchoService to
Microsoft.ServiceBus.Samples.
Important
This tutorial uses the C# namespace Microsoft.ServiceBus.Samples, which is
the namespace of the contract managed type that is used in the configuration file
in Step 6: Configure the WCF Client. You can specify any namespace you want
when you build this sample; however, the tutorial will not work unless you then
modify the namespaces of the contract and service accordingly, in the application
configuration file. The namespace specified in the App.config file must be the
same as the namespace specified in your C# files.
11. Directly after the Microsoft.ServiceBus.Samples namespace declaration, but within the
namespace, define a new interface named IEchoContract and apply the
ServiceContractAttribute attribute to the interface with a namespace value of
http://samples.microsoft.com/ServiceModel/Relay/. The namespace value differs from
the namespace that you use throughout the scope of your code. Instead, the namespace
40
value is used as a unique identifier for this contract. Specifying the namespace explicitly
prevents the default namespace value from being added to the contract name.
[ServiceContract(Name = "IEchoContract", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/")]
public interface IEchoContract
{
}
Note
Typically, the service contract namespace contains a naming scheme that
includes version information. Including version information in the service contract
namespace enables services to isolate major changes by defining a new service
contract with a new namespace and exposing it on a new endpoint. In in this
manner, clients can continue to use the old service contract without having to be
updated. Version information can consist of a date or a build number. For more
information, seeService Versioning. For the purposes of this tutorial, the naming
scheme of the service contract namespace does not contain version information.
12. Within the IEchoContract interface, declare a method for the single operation the
IEchoContract contract exposes in the interface and apply the
OperationContractAttribute attribute to the method that you want to expose as part of
the public Service Bus contract.
[OperationContract]
string Echo(string text);
13. Outside the contract, declare a channel that inherits from both IEchoChannel and also to
the IClientChannel interface, as shown here:
41
A channel is the WCF object through which the host and client pass information to each
other. Later, you will write code against the channel to echo information between the two
applications.
14. From the Build menu, select Build Solution or press F6 to confirm the accuracy of your
work.
Example
Description
The following code example shows a basic interface that defines an Service Bus contract.
Code
using System;
using System.ServiceModel;
namespace Microsoft.ServiceBus.Samples
[OperationContract]
class Program
42
Comments
Now that the interface is created, you can implement the interface, as described in Step 3:
Implement the WCF Contract to use Service Bus.
43
3. Implement the Echo method defined in the IEchoContract interface in the EchoService
class.
public string Echo(string text)
{
Console.WriteLine("Echoing: {0}", text);
return text;
}
4. Click Build. Then click Build Solution to confirm the accuracy of your work.
Note
Steps 1 and 2 are not necessary if you are using Visual Studio 2010 , because
by default, the App.config file is already present in the project.
In Solution Explorer, right-click the EchoService project, select Add. Then click New
Item.
2. In the Add New Item dialog, in the Visual Studio installed templates pane, select
Application Configuration file, and then click Add.
The configuration file is very similar to a WCF configuration file, and includes the service
name, endpoint (that is, the location Service Bus exposes for clients and hosts to
communicate with each other), and the binding (the type of protocol that is used to
communicate). The main difference is that this configured service endpoint refers to a
netTcpRelayBinding, which is not part of the .NET Framework 3.5.
Microsoft.ServiceBus.NetTcpRelayBinding is one of the new bindings introduced with
the Service Bus.
3. In Solution Explorer, click App.config, which currently contains the following XML
elements:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
4. Add a <system.serviceModel> XML element to the App.config file. This is a WCF element
that defines one or more services. This example uses it to define the service name and
endpoint.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
44
</system.serviceModel>
</configuration>
5. Within the <system.serviceModel> tags, add a <services> element. You can define
multiple Service Bus applications in a single configuration file. However, this tutorial
defines only one.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
</services>
</system.serviceModel>
</configuration>
6. Within the <services> element, add a <service> element to define the name of the
service.
<service name="Microsoft.ServiceBus.Samples.EchoService">
</service>
7. Within the <service> element, define the location of the endpoint contract, and also the
type of binding for the endpoint.
<endpoint
contract="Microsoft.ServiceBus.Samples.IEchoContract"
binding="netTcpRelayBinding" />
The endpoint defines where the client will look for the host application. Later, the tutorial
uses this step to create a URI that fully exposes the host through the Service Bus. The
binding declares that we are using TCP as the protocol to communicate with the Service
Bus.
8. Directly after the <services> element, add the following binding extension:
<extensions>
<bindingExtensions>
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCo
llectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
45
9. Click Build, and then click Build Solution to confirm the accuracy of your work.
Example
Description
The following code example shows the implementation of the service contract.
Code
[ServiceBehavior(Name = "EchoService", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/")]
return text;
Example
Description
The following example shows the basic format of the App.config file associated with the service
host.
Code
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceBus.Samples.EchoService">
<endpoint contract="Microsoft.ServiceBus.Samples.IEchoContract"
binding="netTcpRelayBinding" />
</service>
</services>
<extensions>
46
<bindingExtensions>
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement,
Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</bindingExtensions>
</extensions>
</system.serviceModel>
</configuration>
Comments
Now that you have implemented the Service Bus contract and configured your endpoints,
proceed to Step 4: Host and Run a Basic Web Service to Register with Service Bus.
Note
When using a command-line compiler (for example, Csc.exe), you must also
provide the path to the assemblies.
2. In Program.cs, add a using statement for the Microsoft.ServiceBus namespace.
using Microsoft.ServiceBus;
Microsoft.ServiceBus is the namespace that lets you programmatically access many of
the core features of the Service Bus. You will most likely use this namespace in all your
47
Service Bus applications.
3. In the Main() method, create three variables in which to store the service namespace,
issuer name, and issuer secret (a name/password credential) that are read from the
console window.
Console.Write("Your Service Namespace: ");
string serviceNamespace = Console.ReadLine();
Console.Write("Your Issuer Name: ");
string issuerName = Console.ReadLine();
Console.Write("Your Issuer Secret: ");
string issuerSecret = Console.ReadLine();
The issuer name and issuer secret will be used later to access your Service Bus project.
The service namespace is passed as a parameter to CreateServiceUri to create a
service URI.
4. Using a Microsoft.ServiceBus.TransportClientEndpointBehavior object, declare that
you will be using a shared secret as the credential type. Add the following code directly
underneath the code added in the last step.
TransportClientEndpointBehavior
sharedSecretServiceBusCredential = new
TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.TokenProvider =
TokenProvider.CreateSharedSecretTokenProvider(issuerName,
issuerSecret);
ServiceBusEnvironment.SystemConnectivity.Mode =
ConnectivityMode.AutoDetect;
48
The connectivity mode describes the protocol the service uses to communicate with the
Service Bus; either HTTP or TCP. Using the default setting AutoDetect, the service will
attempt to connect to the Service Bus over TCP, if it is available, and HTTP if TCP is not
available. Note that this differs from the protocol the service specifies for client
communication. That protocol is determined by the binding used. For example, a service
can use the Microsoft.ServiceBus.BasicHttpRelayBinding binding, which specifies
that its endpoint (exposed on the Service Bus) communicates with clients over HTTP.
That same service could specify ConnectivityMode.AutoDetect so that the service
communicates with the Service Bus over TCP.
2. Create the service host, using the URI created earlier in this section.
ServiceHost host = new ServiceHost(typeof(EchoService),
address);
The service host is the WCF object that instantiates the service. Here, you pass it the
type of service you want to create (an EchoService type), and also to the address at which
you want to expose the service.
3. At the top of the Program.cs file, add references to System.ServiceModel.Description
and Microsoft.ServiceBus.Description.
using System.ServiceModel.Description;
using Microsoft.ServiceBus.Description;
4. Back in Main(), configure the endpoint to enable public access.
IEndpointBehavior serviceRegistrySettings = new
ServiceRegistrySettings(DiscoveryType.Public);
This step informs the Service Bus that your application can be found publicly by
examining the Service Bus ATOM feed for your project. If you set DiscoveryType to
private, a client would still be able to access the service. However, the service would not
appear when it searches the Service Bus namespace. Instead, the client would have to
know the endpoint path beforehand. For more information, see Discovering and Exposing
a Service Bus Service.
5. Apply the service credentials to the service endpoints defined in the App.config file:
foreach (ServiceEndpoint endpoint in
host.Description.Endpoints)
{
endpoint.Behaviors.Add(serviceRegistrySettings);
endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
}
As stated in the previous step, you could have declared multiple services and endpoints
in the configuration file. If you had, this code would traverse the configuration file and
search for every endpoint to which it should apply your credentials. However, for this
tutorial, the configuration file has only one endpoint.
49
To open the service host
1. Open the service.
host.Open();
2. Inform the user that the service is running, and explain how to shut down the service.
Console.WriteLine("Service address: " + address);
Console.WriteLine("Press [Enter] to exit");
Console.ReadLine();
3. When finished, close the service host.
host.Close();
4. Press F6 to build the project.
Example
Description
The following example includes the service contract and implementation from previous steps in
the tutorial, and hosts the service in a console application. Compile the following into an
executable named EchoService.exe.
Code
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Description;
namespace Microsoft.ServiceBus.Samples
[OperationContract]
50
public interface IEchoChannel : IEchoContract, IClientChannel { };
return text;
class Program
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;
51
sharedSecretServiceBusCredential.TokenProvider =
TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerSecret);
endpoint.Behaviors.Add(serviceRegistrySettings);
endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
host.Open();
Console.ReadLine();
host.Close();
52
}
Comments
Now that the interface is created, proceed to Step 5: Create a WCF Client for the Service
Contract to implement the interface.
Note
For the purposes of this tutorial, both the client and the service run on the same network
and computer. However, this is not required. The advantage of using the Service Bus is
to enable applications across network boundaries to seamlessly communicate.
Time to completion: 10 minutes
Example
Description
The following code shows the current status of the Program.cs file in the EchoClient project.
Code
using System;
using Microsoft.ServiceBus;
using System.ServiceModel;
namespace Microsoft.ServiceBus.Samples
54
[ServiceContract(Name = "IEchoContract", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/")]
[OperationContract]
class Program
Comments
Now that the interface is created, proceed to Step 6: Configure the WCF Client to implement the
interface.
Note
55
Steps 1 and 2 are not necessary if you are using Visual Studio 2010 , because
by default, the App.config file is already present in the project.
Right-click the client project, select Add, New Item.
2. In the Add New Item dialog, in the Templates pane, select Application Configuration
File. Then click Add.
3. In Solution Explorer, in the client project, double-click App.config to open the file,
which currently contains the following XML elements:
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.0"/></startup></configuration>
4. Add an XML element to the App.config file for system.serviceModel.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
</system.serviceModel>
</configuration>
This element declares that your application uses WCF-style endpoints. As stated
previously, much of the configuration of an Service Bus application is identical to a WCF
application; the main difference is the location to which the configuration file points.
5. Within the system.serviceModel element, add a <client> element.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
</client>
</system.serviceModel>
</configuration>
This step declares that you are defining a WCF-style client application.
6. Within the client element, define the name, contract, and binding type for the endpoint.
<endpoint name="RelayEndpoint"
contract="Microsoft.ServiceBus.Samples.IEchoContract"
56
binding="netTcpRelayBinding"/>
This step defines the name of the endpoint, the contract defined in the service, and the
fact that the client application uses TCP to communicate with the Service Bus. The
endpoint name will be used in the next step, to link this endpoint configuration with the
service URI.
7. Directly after the <client> element, add the following binding extension:
<extensions>
<bindingExtensions>
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCo
llectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
8. Click File. Then click Save All.
Example
Description
The following code sample shows the App.config file for the Echo client.
Code
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint name="RelayEndpoint"
contract="Microsoft.ServiceBus.Samples.IEchoContract"
binding="netTcpRelayBinding"/>
</client>
<extensions>
<bindingExtensions>
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement,
Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</bindingExtensions>
57
</extensions>
</system.serviceModel>
</configuration>
Comments
Now that you have configured the client application, proceed to Step 7: Implement WCF Client to
Call the Service Bus to implement the rest of the application.
58
Console.Write("Your Issuer Name: ");
string issuerName = Console.ReadLine();
Console.Write("Your Issuer Secret: ");
string issuerSecret = Console.ReadLine();
3. Create the URI that defines the location of the host in your Service Bus project.
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb",
serviceNamespace, "EchoService");
59
{
Console.WriteLine("Server echoed: {0}",
channel.Echo(input));
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
input = Console.ReadLine();
}
Note that the code uses the instance of the channel object as a proxy for the service.
9. Close the channel, and close the factory.
channel.Close();
channelFactory.Close();
60
The service application starts and prints the address it is listening on to the console
window as seen in the following example.
Service address: sb://mynamespace.servicebus.windows.net/EchoService/
Enter some text to send to the service application and press ENTER.
This text is sent to the service through the Echo service operation and appears in the
service console window as in the following example output.
Echoing: My sample text
The client application receives the return value of the Echo operation, which is the original
text, and prints it to its console window. The following is an example output from the client
console window.
Server echoed: My sample text
9. You can continue sending text messages from the client to the service in this manner.
When you are finished, press ENTER in the client and service console windows to end
both applications.
Example
Description
The following example shows how to create a client application, how to call the operations of the
service, and how to close the client after the operation call is finished.
Code
using System;
using Microsoft.ServiceBus;
using System.ServiceModel;
61
namespace Microsoft.ServiceBus.Samples
[OperationContract]
class Program
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;
sharedSecretServiceBusCredential.TokenProvider =
TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerSecret);
62
ChannelFactory<IEchoChannel> channelFactory = new
ChannelFactory<IEchoChannel>("RelayEndpoint", new EndpointAddress(serviceUri));
channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
channel.Open();
try
catch (Exception e)
input = Console.ReadLine();
channel.Close();
channelFactory.Close();
Comments
Ensure that the service is running before you start the client. For more information, see Step 4:
Host and Run a Basic Web Service to Register with Service Bus.
63
Security
In This Section
Service Bus Brokered Messaging .NET Tutorial
64
In This Section
Step 1: Introduction and Prerequsites
Step 2: Create Management Credentials
Step 3: Send Messages to the Queue
Step 4: Receive Messages from the Queue
Step 5: Build and Run the QueueSample Application
See Also
Service Bus Relayed Messaging Tutorial
65
under Other Languages), click the Console Application template, and name it
QueueSample. Use the default Location. Click OK to create the project.
3. In the Solution Explorer, right-click the name of your project (in this example,
QueueSample), and click Properties.
4. Click the Application tab on the left, then select .NET Framework 4 from the Target
framework: dropdown. Click Yes when prompted to reload the project.
5. Add references to the Microsoft.ServiceBus, System.Runtime.Serialization, and
System.ServiceModel assemblies:
a. In the Solution Explorer, right-click the References folder under the project folder
and then click Add Reference….
b. Select the .NET tab in the Add Reference dialog and scroll down until you see
Microsoft.ServiceBus, select it, and then click OK.
c. Repeat the above step for System.Runtime.Serialization and
System.ServiceModel.
6. In the Solution Explorer, double-click the Program.cs file to open it in the Visual Studio
editor. Change the namespace name from its default name of QueueSample to
Microsoft.ServiceBus.Samples.
namespace Microsoft.ServiceBus.Samples
{
…
7. Add using statements for the Microsoft.ServiceBus, Microsoft.ServiceBus.Messaging ,
Microsoft.ServiceBus.Description, System.IO, and System.Data namespaces.
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.ServiceBus.Description;
using System.Data;
using System.IO;
8. Create a text file named Data.csv, and copy in the following comma-delimited text.
IssueID,IssueTitle,CustomerID,CategoryID,SupportPackage,Prior
ity,Severity,Resolved
1,Package lost,1,1,Basic,5,1,FALSE
2,Package damaged,1,1,Basic,5,1,FALSE
3,Product defective,1,2,Premium,5,2,FALSE
4,Product damaged,2,2,Premium,5,2,FALSE
5,Package lost,2,2,Basic,5,2,TRUE
6,Package lost,3,2,Basic,5,2,FALSE
7,Package damaged,3,7,Premium,5,3,FALSE
8,Product defective,3,2,Premium,5,3,FALSE
66
9,Product damaged,4,6,Premium,5,3,TRUE
10,Package lost,4,8,Basic,5,3,FALSE
11,Package damaged,5,4,Basic,5,4,FALSE
12,Product defective,5,4,Basic,5,4,FALSE
13,Package lost,6,8,Basic,5,4,FALSE
14,Package damaged,6,7,Premium,5,5,FALSE
15,Product defective,6,2,Premium,5,5,FALSE
Save and close the Data.csv file, and remember the location to which you saved it.
9. In the Solution Explorer, right-click the name of your project (in this example,
QueueSample), click Add, then click Existing Item.
10. Browse to the Data.csv file that you created in step 6. Click the file, then click Add. You
may need to ensure that All Files (*.*) is selected in the file type dropdown.
2. Outside the Main() method, define a ParseCSV() method that parses the list of messages
in Data.csv and loads the messages into a System.Data.DataTable table, as shown
here. The method returns a DataTable object.
static DataTable ParseCSVFile()
{
DataTable tableIssues = new DataTable("Issues");
string path = @"..\..\data.csv";
try
67
{
using (StreamReader readFile = new
StreamReader(path))
{
string line;
string[] row;
return tableIssues;
}
3. In the Main() method, add a statement that calls the ParseCSVFile() method:
public static void Main(string[] args)
{
68
}
69
MessageList = GenerateMessages(issues);
}
// Issuer name
Console.Write("Please enter the issuer name to use: ");
IssuerName = Console.ReadLine();
// Issuer key
Console.Write("Please enter the issuer key to use: ");
IssuerKey = Console.ReadLine();
}
70
3. In the Main() method, directly below the call to GenerateMessages(), add a statement that
calls the CollectUserInput() method:
public static void Main(string[] args)
{
71
{
// Create management credentials
TokenProvider credentials =
TokenProvider.CreateSharedSecretTokenProvider(IssuerName,
IssuerKey);
}
Example
Description
At this point, your code should look similar to the following:
Code
namespace Microsoft.ServiceBus.Samples
CollectUserInput();
72
// Populate test data
issues = ParseCSVFile();
MessageList = GenerateMessages(issues);
TokenProvider credentials =
TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerKey);
ServiceNamespace = Console.ReadLine();
// Issuer name
IssuerName = Console.ReadLine();
// Issuer key
IssuerKey = Console.ReadLine();
73
static List<BrokeredMessage> GenerateMessages(DataTable issues)
// Iterate through the table and create a brokered message for each row
message.Properties.Add(property.ColumnName, item[property]);
result.Add(message);
return result;
string line;
string[] row;
line = readFile.ReadLine();
tableIssues.Columns.Add(columnTitle);
74
while ((line = readFile.ReadLine()) != null)
row = line.Split(',');
tableIssues.Rows.Add(row);
return tableIssues;
Comments
In the next step, you create the queue to which you will send messages.
Console.WriteLine("Processing message
(sleeping...)");
Thread.Sleep(1000);
76
}
Example
Description
The following code contains the complete QueueSample application.
Code
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
77
using Microsoft.ServiceBus.Description;
using System.Data;
using System.IO;
namespace Microsoft.ServiceBus.Samples
class Program
issues = ParseCSVFile();
MessageList = GenerateMessages(issues);
CollectUserInput();
Queue();
78
string path = @"..\..\data.csv";
try
string line;
string[] row;
line = readFile.ReadLine();
tableIssues.Columns.Add(columnTitle);
row = line.Split(',');
tableIssues.Rows.Add(row);
catch (Exception e)
Console.WriteLine("Error:" + e.ToString());
return tableIssues;
79
// Iterate through the table and create a brokered message for each row
message.Properties.Add(property.ColumnName, item[property]);
result.Add(message);
return result;
ServiceNamespace = Console.ReadLine();
// Issuer name
IssuerName = Console.ReadLine();
// Issuer key
IssuerKey = Console.ReadLine();
TokenProvider credentials =
80
TokenProvider.CreateSharedSecretTokenProvider(IssuerName, IssuerKey);
//QueueDescription myQueue;
//myQueue = namespaceClient.CreateQueue("IssueTrackingQueue");
namespaceClient.CreateQueue("IssueTrackingQueue");
MessagingFactory factory =
MessagingFactory.Create(ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace,
string.Empty), credentials);
QueueClient myQueueClient =
factory.CreateQueueClient("IssueTrackingQueue");
// Create a sender
// Send messages
issue.Label = issue.Properties["IssueTitle"].ToString();
myQueueClient.Send(issue);
BrokeredMessage message;
81
{
message.Complete();
Thread.Sleep(1000);
factory.Close();
myQueueClient.Close();
namespaceClient.DeleteQueue("IssueTrackingQueue");
82
prompted, enter the name of the service namespace, the issuer name, and the key that
you obtained in step 4.
In This Section
Step 1: Create a Service Namespace for the REST Queue and Topic/Subscription Tutorial
Step 2: Create a Console Client
Step 3: Create Management Credentials
Step 4: Create the Queue
Step 5: Send a Message to the Queue
Step 6: Receive a Message from the Queue
Step 7: Create a Topic and Subscription
Step 8: Retreive Message Resources
Step 9: Build and Run the Application
How to: Create a Service Namespace for Queues, Topics, and Subscriptions
83
Step 2: Create a Console Client
This is the second of nine tasks required to create a basic REST-style queue and
publication/subscription application that uses the Windows Azure Service Bus.
Service Bus queues enable you to store messages in a first-in, first-out queue. Topics and
subscriptions implement a publish/subscribe pattern; you create a topic and then create one or
more subscriptions associated with that topic. When messages are sent to the topic, they are
immediately sent to the subscribers of that topic.
The code in this tutorial:
• Uses your service namespace, issuer name, and issuer key to contact the Windows Azure
Access Control Service (ACS) to obtain a Simple Web Token (SWT) to gain access to your
Service Bus service namespace resources.
• Creates a queue, sends a message to the queue, and reads the message from the queue.
• Creates a topic, a subscription to that topic, and sends and reads the message from the
subscription.
• Retreives all the queue, topic, and subscription information – including subscription rules --
from the Service Bus for your service namespace.
• It then deletes the queue, topic, and subscription resources.
Because the service is a REST-style Web service, there are no special types involved, as the
entire exchange involves strings. This means that the Visual Studio project must make no
references other than the defaults, although if your configuration has modified the defaults, you
may have to add some basic .NET Framework references to the code.
After obtaining the service namespace and credentials in step 1, the next step is to create a basic
Visual Studio console application.
84
using System.Text;
using System.Xml;
5. If necessary, rename the service namespace for the program from the Visual Studio
default to Microsoft.ServiceBus.Samples.
6. Inside the Program class, add the following global variables:
static string serviceNamespace;
static string baseAddress;
static string token;
const string sbHostName = "servicebus.windows.net";
const string acsHostName = "accesscontrol.windows.net";
7. Inside the Main() method, copy the following code:
Console.Write("Enter your service namespace: ");
serviceNamespace = Console.ReadLine();
85
string topicName = "Topic" + Guid.NewGuid().ToString();
string subscriptionName = "Subscription" +
Guid.NewGuid().ToString();
CreateTopic(topicName);
CreateSubscription(topicName, subscriptionName);
SendMessage(topicName, "msg2");
// Get an Atom feed with all the rules for the topic and
subscritpion we just created
Console.WriteLine(GetResources(topicName +
"/Subscriptions/" + subscriptionName + "/Rules"));
86
// Get an Atom feed with all the topics in the namespace,
it shouldn't have the one we created now
Console.WriteLine(GetResources("$Resources/Topics"));
87
To create a GetToken() method
1. Paste the following code after the Main() method in the Program class:
private static string GetToken(string issuerName, string
issuerSecret)
{
var acsEndpoint = "https://" + serviceNamespace + "-sb."
+ acsHostName + "/WRAPv0.9/";
string responseString =
Encoding.UTF8.GetString(response);
88
Step 4: Create the Queue
This is the fourth of nine tasks required to create a basic REST-style queue and
publication/subscription application that uses the Service Bus.
The next step is to write a method that uses the REST-style HTTP PUT command to create a
queue.
To create a queue
1. Paste the following code directly beneath the GetToken() code you added in step 3:
// Uses HTTP PUT to create the queue
private static string CreateQueue(string queueName, string
token)
{
// Create the URI of the new queue, note that this uses
the HTTPS scheme
string queueAddress = baseAddress + queueName;
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.Authorization] =
token;
89
Step 5: Send a Message to the Queue
This is the fifth of nine tasks required to create a basic REST-style queue and
publication/subscription application that uses the Service Bus.
In this step, you add a method that uses the REST-style HTTP POST command to send a
message to the queue you created in the previous step.
webClient.UploadData(fullAddress, "POST",
Encoding.UTF8.GetBytes(body));
}
90
1. Paste the following code directly beneath the SendMessage() code you added in step 5:
// Receives and deletes the next message from the given
resource (Queue, Topic, or Subscription)
// using the resourceName, the SWT token, and an HTTP DELETE
request.
private static string ReceiveAndDeleteMessage(string
resourceName)
{
string fullAddress = baseAddress + resourceName +
"/messages/head" + "?timeout=60";
Console.WriteLine("\nRetrieving message from {0}",
fullAddress);
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.Authorization] =
token;
Console.WriteLine(responseStr);
return responseStr;
}
To create a topic
1. Paste the following code directly beneath the ReceiveAndDeleteMessage() code you added
in step 6:
// Creates a Topic with the given topic name and the SWT
token
91
// Using an HTTP PUT request.
private static string CreateTopic(string topicName)
{
var topicAddress = baseAddress + topicName;
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.Authorization] =
token;
To create a subscription
1. The following code creates a subscription to the topic you created in the previous section.
Add the following code directly beneath the CreateTopic() definition:
private static string CreateSubscription(string topicName,
string subscriptionName)
{
var subscriptionAddress = baseAddress + topicName +
"/Subscriptions/" + subscriptionName;
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.Authorization] =
92
token;
byte[] response =
webClient.UploadData(subscriptionAddress, "PUT",
Encoding.UTF8.GetBytes(putData));
return Encoding.UTF8.GetString(response);
}
93
webClient.Headers[HttpRequestHeader.Authorization] =
token;
Console.WriteLine("\nGetting resources from {0}",
fullAddress);
return FormatXml(webClient.DownloadString(fullAddress));
}
94
using (XmlTextWriter writer = new XmlTextWriter(new
StringWriter(builder)))
{
writer.Formatting = Formatting.Indented;
document.Save(writer);
}
return builder.ToString();
}
Example
Description
The following example is the complete code, as it should appear after following steps 1 through 8:
using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
namespace Microsoft.ServiceBus.Samples
95
class Program
serviceNamespace = Console.ReadLine();
try
// Get a SWT token from the Access Control Service, given the issuerName
and issuerSecret values.
// Create and put a message in the queue using the SWT token.
CreateQueue(queueName, token);
SendMessage(queueName, "msg1");
96
string msg = ReceiveAndDeleteMessage(queueName);
CreateTopic(topicName);
CreateSubscription(topicName, subscriptionName);
SendMessage(topicName, "msg2");
//System.Threading.Thread.Sleep(500);
Console.WriteLine(ReceiveAndDeleteMessage(topicName + "/Subscriptions/" +
subscriptionName));
Console.WriteLine(GetResources("$Resources/Queues"));
Console.WriteLine(GetResources("$Resources/Topics"));
// Get an Atom feed with all the subscriptions for the topic we just
created
Console.WriteLine(GetResources(topicName + "/Subscriptions"));
// Get an Atom feed with all the rules for the topic and subscritpion we
just created
Console.WriteLine(GetResources(topicName + "/Subscriptions/" +
subscriptionName + "/Rules"));
DeleteResource(queueName);
DeleteResource(topicName);
97
// Get an Atom feed with all the topics in the namespace, it shouldn't
have the one we created now
Console.WriteLine(GetResources("$Resources/Topics"));
// Get an Atom feed with all the queues in the namespace, it shouldn't
have the one we created now
Console.WriteLine(GetResources("$Resources/Queues"));
if (response != null)
Console.WriteLine(new
StreamReader(response.GetResponseStream()).ReadToEnd());
else
Console.WriteLine(we.ToString());
Console.ReadLine();
// Note that the realm used when requesting a token uses the HTTP scheme,
even though
98
// calls to the service are always issued over HTTPS
values.Add("wrap_name", issuerName);
values.Add("wrap_password", issuerSecret);
values.Add("wrap_scope", realm);
// Create the URI of the new Queue, note that this uses the HTTPS scheme
webClient.Headers[HttpRequestHeader.Authorization] = token;
<content type=""application/xml"">
99
<QueueDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""
xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"" />
</content>
</entry>";
return Encoding.UTF8.GetString(response);
// Sends a message to the "queueName" queue, given the name, the value to
enqueue, and the SWT token
webClient.Headers[HttpRequestHeader.Authorization] = token;
// Receives and deletes the next message from the given resource (Queue, Topic,
or Subscription)
// using the resourceName, the SWT token, and an HTTP DELETE request.
webClient.Headers[HttpRequestHeader.Authorization] = token;
100
byte[] response = webClient.UploadData(fullAddress, "DELETE", new byte[0]);
Console.WriteLine(responseStr);
return responseStr;
// Creates a Topic with the given topic name and the SWT token
webClient.Headers[HttpRequestHeader.Authorization] = token;
<content type=""application/xml"">
<TopicDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""
xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"" />
</content>
</entry>";
return Encoding.UTF8.GetString(response);
101
var subscriptionAddress = baseAddress + topicName + "/Subscriptions/" +
subscriptionName;
webClient.Headers[HttpRequestHeader.Authorization] = token;
<content type=""application/xml"">
<SubscriptionDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""
xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"" />
</content>
</entry>";
return Encoding.UTF8.GetString(response);
webClient.Headers[HttpRequestHeader.Authorization] = token;
return FormatXml(webClient.DownloadString(fullAddress));
webClient.Headers[HttpRequestHeader.Authorization] = token;
102
Console.WriteLine("\nDeleting resource at {0}", fullAddress);
return Encoding.UTF8.GetString(response);
document.Load(new StringReader(inputXml));
writer.Formatting = Formatting.Indented;
document.Save(writer);
return builder.ToString();
103
In This Section
Step 1: Sign up for an Account for the REST Tutorial
Step 2: Define a REST-based WCF Service Contract to use with Service Bus
Step 3: Implement a REST-based WCF Service Contract to use Service Bus
Step 4: Host the REST-based WCF Service to use the Service Bus
104
System.ServiceModel.Web.WebGetAttribute to link a method to HTTP GET. This allows the
Service Bus to accurately retrieve and interpret commands sent to the interface.
Expected time to completion: 10 minutes.
Note
When using a command-line compiler (for example, Csc.exe), you must also
provide the path of the assemblies. By default, on a computer that is running
Windows°7 for example, the path is:
Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation.
5. Repeat the previous step to add a reference to the System.ServiceModel.Web.dll
assembly.
6. Add a using statement for the System.ServiceModel, System.ServiceModel.Channels,
System.ServiceModel.Web, and System.IO namespaces.
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
105
applications.
7. Rename the namespace for the program from the Visual Studio default to
Microsoft.ServiceBus.Samples.
namespace Microsoft.ServiceBus.Samples
{
...
8. Directly after the namespace declaration, define a new interface named IImageContract
and apply the ServiceContractAttribute attribute to the interface with a value of
http://samples.microsoft.com/ServiceModel/Relay/. The namespace value differs from
the namespace that you use throughout the scope of your code. The namespace value is
used as a unique identifier for this contract, and should have versioning information. For
more information, see, see Service Versioning. Specifying the namespace explicitly
prevents the default namespace value from being added to the contract name.
[ServiceContract(Name = "ImageContract", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/RESTTutorial
1")]
public interface IImageContract
{
}
9. Within the IImageContract interface, declare a method for the single operation the
IImageContract contract exposes in the interface and apply the
OperationContractAttribute attribute to the method that you want to expose as part of
the public Service Bus contract.
public interface IImageContract
{
[OperationContract]
Stream GetImage();
}
10. Next to the OperationContract attribute, apply the WebGet attribute.
106
Doing so allows the Service Bus to route HTTP GET requests to GetImage, and to
translate the return values of GetImage into an HTTP GETRESPONSE reply. Later in the
tutorial, you will use a Web browser to access this method, and to display the image in
the browser.
11. Directly underneath the IImageContract definition, declare a channel that inherits from
both the IImageContract and IClientChannel interfaces.
[ServiceContract(Name = "IImageContract", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/")]
public interface IImageContract
{
[OperationContract, WebGet]
Stream GetImage();
}
Example
Description
The following code example shows a basic interface that defines an Service Bus contract.
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
107
namespace Microsoft.ServiceBus.Samples
[OperationContract, WebGet]
Stream GetImage();
class Program
Comments
Now that the interface is created, proceed to Step 3: Implement a REST-based WCF Service
Contract to use Service Bus to implement the interface.
See Also
Step 3: Implement a REST-based WCF Service Contract to use Service Bus
When adding the file, make sure that All Files (*.*) is selected in the drop-down list next
to the File name: field. The rest of this tutorial assumes that the name of the image is
109
“image.jpg”. If you have a different .jpg, you will have to rename the image, or change
your code to compensate.
4. To make sure that the running service can find the image file, in Solution Explorer right-
click the image file. In the Properties pane, set Copy to Output Directory to Copy if
newer.
5. Add references to the System.Drawing.dll, System.Runtime.Serialization.dll, and
Microsoft.ServiceBus.dll assemblies to the project, and also to the following associated
using statements.
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;
6. Define a constructor that loads the bitmap and prepares to send it to the client browser:
class ImageService : IImageContract
{
const string imageFileName = "image.jpg";
Image bitmap;
public ImageService()
{
this.bitmap = Image.FromFile(imageFileName);
}
}
7. Directly underneath the previous code, add the following GetImage method in the
ImageService class to return an HTTP message that contains the image:
stream.Position = 0;
WebOperationContext.Current.OutgoingResponse.ContentType =
110
"image/jpeg";
return stream;
}
This implementation uses MemoryStream to retrieve the image and prepare it for
streaming to the browser. It starts the stream position at zero, declares the stream
content as a jpeg, and streams the information.
8. From the Build menu, click Build Solution to build the whole solution.
To define the configuration to run the Web service on the Service Bus
1. Right-click the ImageListener project. Then click Add, New Item.
2. In the Add New Item dialog, in the Templates pane, select Application Configuration.
Then click Add.
The configuration file resembles a WCF configuration file, and includes the service name,
endpoint (that is, the location Service Bus exposes for clients and hosts to communicate
with each other), and binding (the type of protocol that is used to communicate). The
main difference here is that the configured service endpoint refers to a
Microsoft.ServiceBus.WebHttpRelayBinding binding, which is not part of the .NET
Framework. Microsoft.ServiceBus.WebHttpRelayBinding is one of the new bindings
introduced with the Service Bus. For more information about how to configure an Service
Bus application, see Configuring a WCF Service to Register with the Service Bus.
3. In Solution Explorer, click App.config, which currently contains the following XML
elements:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
4. Add an XML element to the App.config file for system.serviceModel. This is a WCF
element that defines one or more services. Here, it is used to define the service name
and endpoint.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
</system.serviceModel>
</configuration>
5. Within the system.serviceModel element, add a <bindings> element that has the following
content. This defines the bindings used in the application. You can define multiple
111
bindings, but for this tutorial you are defining only one.
<bindings>
<!-- Application Binding -->
<webHttpRelayBinding>
<binding name="default">
<security relayClientAuthenticationType="None" />
</binding>
</webHttpRelayBinding>
</bindings>
This step defines an Service Bus Microsoft.ServiceBus.WebHttpRelayBinding binding
with the relayClientAuthenticationType as None. This indicates that an endpoint using
this binding will not require a client credential.
6. Below the <bindings> element, add a <services> element. As with the bindings, you can
define multiple services in a single configuration file. However, for this tutorial, you define
only one.
<services>
<!-- Application Service -->
<service name="Microsoft.ServiceBus.Samples.ImageService"
behaviorConfiguration="default">
<endpoint name="RelayEndpoint"
contract="Microsoft.ServiceBus.Samples.IImageContract"
binding="webHttpRelayBinding"
bindingConfiguration="default"
behaviorConfiguration="sharedSecretClientCredentials"
address="" />
</service>
</services>
This step configures a service that uses the previously defined default
webHttpRelayBinding. It also uses the default sharedSecretClientCredentials, which is
defined in the next step.
7. Below the <services> element, create a <behaviors> element, with the following content,
replacing “ISSUER_NAME” and “ISSUER_SECRET” with your issuer name and secret,
respectively.
<behaviors>
112
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior
credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="ISSUER_NAME"
issuerSecret="ISSUER_SECRET" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="default">
<serviceDebug httpHelpPageEnabled="false"
httpsHelpPageEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
The sharedSecretClientCredentials behavior defines the type of credentials the service
uses to access the Service Bus: SharedSecret. In addition, the actual issuer names and
issuer secrets are stored in the App.config file. Note that storing secrets in clear text is
not considered good programming practice for production code. Be sure to implement
more rigorous security in your own code.
This code also defines the default debugging behavior, which consists of turning off the
HTTP and HTTPS help pages.
8. From the Build menu, select Build Solution to build the whole solution.
Example
Description
The following code shows the contract and service implementation for a REST-based service that
is running on the Service Bus using the WebHttpRelayBinding binding.
Code
using System;
113
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;
namespace Microsoft.ServiceBus.Samples
[OperationContract, WebGet]
Stream GetImage();
Image bitmap;
114
public ImageService()
this.bitmap = Image.FromFile(imageFileName);
this.bitmap.Save(stream, ImageFormat.Jpeg);
stream.Position = 0;
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
return stream;
class Program
Example
Description
The following example shows the App.config file associated with the service.
Code
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
115
<!-- Application Binding -->
<webHttpRelayBinding>
<binding name="default">
<!-- Turn off client authentication so that client does not need to present credential
through browser or fiddler -->
</binding>
</webHttpRelayBinding>
</bindings>
<services>
<service name="Microsoft.ServiceBus.Samples.ImageService"
behaviorConfiguration="default">
<endpoint name="RelayEndpoint"
contract="Microsoft.ServiceBus.Samples.IImageContract"
binding="webHttpRelayBinding"
bindingConfiguration="default"
behaviorConfiguration="sharedSecretClientCredentials"
address="" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
116
<behavior name="default">
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Comments
Now that you have configured and implemented the Web service contract, proceed to Step 4:
Host the REST-based WCF Service to use the Service Bus.
117
To run the Web service host
1. Open the service.
host.Open();
The service is now running.
2. Display a message indicating that the service is running, and how to stop the service.
Console.WriteLine("Copy the following address into a browser
to see the image: ");
Console.WriteLine(address + "GetImage");
Console.WriteLine();
Console.WriteLine("Press [Enter] to exit");
Console.ReadLine();
3. When finished, close the service host.
host.Close();
Example
Description
The following example includes the service contract and implementation from previous steps in
the tutorial and hosts the service in a console application. Compile the following into an
executable named ImageListener.exe..
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;
118
namespace Microsoft.ServiceBus.Samples
[OperationContract, WebGet]
Stream GetImage();
Image bitmap;
public ImageService()
this.bitmap = Image.FromFile(imageFileName);
this.bitmap.Save(stream, ImageFormat.Jpeg);
stream.Position = 0;
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
119
return stream;
class Program
host.Open();
Console.WriteLine(address + "GetImage");
Console.WriteLine();
Console.ReadLine();
host.Close();
120
Developing Applications that Use the Service
Bus
The Windows Azure Service Bus can be thought of as a “relay in the sky” that enables two
applications to communicate securely regardless of where they may be located. At the highest
conceptual level, using the Service Bus requires:
1. One Web service that is trusted by the Access Control service to create endpoints and
receive and send messages (typically responses but also event notifications) from the
Service Bus endpoint that it creates.
2. One client application that is trusted by the Access Control service to send and receive
messages (typically requests and responses but also event notifications) at a Service Bus
endpoint.
There is only one difference between the two Web service applications: the first Web service is
trusted by Access Control to create an endpoint—that is, an address, or Uniform Resource
Indicator (URI)—with Service Bus. For more information about endpoints and addresses and how
they are used in Windows Communication Foundation (WCF) and the Service Bus, see
Specifying an Endpoint Address. The second Web application (the client), however, cannot
create, affect, or manage the registered Service Bus endpoint; instead, it is trusted by Access
Control to interact with endpoints that are already registered.
Typically, the former type of application is referred to as a service (instead of client or calling
application), because without a controlling or managing Web service, the Service Bus would have
no endpoints with which other Web-enabled applications can communicate. Web applications that
interact with a pre-existing Service Bus endpoint are conventionally referred to as Web service
client applications, because they consume the features available at a registered Service Bus
endpoint.
Overview
This topic provides an overview of the technical features that the Service Bus provides at a high
level. The following additional topics in this section describe application development with the
Service Bus from the point of view of a development lifecycle. Not every development goal
requires starting at any one point in the cycle; if you have to develop a client that invokes a
service published by the Service Bus, you do not have to read about publishing a service
endpoint. Instead, start with Building a Service Bus Client Application.
This section contains the following topics, starting with a development lifecycle outline that
describes the steps in the context of your own development processes.
• Overview of Service Bus Messaging Patterns
• Service Bus Programming Lifecycle
• Service Bus Authentication and Authorization with the Access Control Service
• Service Bus Bindings
• Designing a WCF Contract for the Service Bus
121
• Configuring a WCF Service to Register with the Service Bus
• Securing and Authenticating a Service Bus Connection
• Building a Service for the Service Bus
• Building a Service Bus Client Application
• Discovering and Exposing a Service Bus Service
• Working with a Service Bus Message Buffer
122
How Much Can I Do with the Service Bus?
The Service Bus is made to enable bidirectional communication between service-oriented
applications anywhere in the world. However, the real world is full of limits, and the Service Bus
does not support every protocol you might ever want or need. For example, in this release, the
system-supplied bindings support only a subset of the protocols supported by WCF. What
happens when you want to use a protocol that is not supported by the system-supplied bindings?
The answer is that you can either implement a WCF custom binding that does support your
required protocol – or you can create a bridge between any two endpoints that enables a
bidirectional stream. As the Service Bus securely exposes service contracts if the contract
specifies a two-way stream, you can then host that service on the Service Bus and exchange
binary data – that is, any custom protocol – using the Service Bus. You can even associate ports
on either side with the binary stream, which enables pre-existing applications to communicate
through the Service Bus using their own proprietary protocol. Finally, you are doing this secured
by tokens from Access Control and through firewalls and NAT routers.
Choosing Namespaces
Once that has been accomplished, you must create a project and create some namespaces that
scope the work that you will be doing. Namespaces are scoping mechanisms, just as they are in
.NET programming or in their use in XML.
123
The namespaces you create must be unique across all Service Bus and Access Control
accounts; when you create a namespace in a Windows Azure project, you are declaring a base
or root namespace that is owned and secured by you. That root namespace is the namespace
that is used to manage security tokens in the Access Control service, and it is a namespace
under which you can register any number of services related to your work. (Note that you can
declare multiple namespaces in a project; each one is completely isolated from the others for all
work that you may do.) For example, if you use the Windows Azure portal to declare a
namespace of contoso-samples, the Service Bus creates the resources that you must have in
order to host, secure, and bill for services underneath the complete namespace URI <protocol
scheme>://contoso-samples.servicebus.windows.net/ (where protocol scheme is in the end
either sb, http, or https, depending on which protocol schemes your endpoints require when you
publish them).
The important things to note about the namespace created are as follows:
• It is location and transport independent. Knowing a namespace provides no information about
the transport used or about the location or type of service endpoint that is registered with the
Service Bus. (You can publish service metadata to all clients so that they can discover your
functionality; but you must take that step yourself. By default, this information is kept private.)
• Creating service names underneath the namespace is a way of partitioning data and
functionality that makes sense to your work environment.
An example can illustrate the second point. Given a registered namespace of contoso-samples
(again, the fully qualified namespace is contoso-samples.servicebus.windows.net), the following
endpoint URIs have names that indicate logical geographical divisions in your company in order
to expose the same structural functionality but secured differently depending on local
considerations:
sb://contoso-samples.servicebus.windows.net/redmond
sb://contoso-samples.servicebus.windows.net/paris
sb://contoso-samples.servicebus.windows.net/tokyo
The root namespace of contoso-samples.servicebus.windows.net can then be used with the
Access Control service to provide secure tokens that enable interaction with one or more of the
local services as is appropriate for the business requirements. The previous example
demonstrates the use of namespaces and endpoints to partition functionality by geographical
location. However, you can use namespaces and names to partition functionality and data by any
logical category you want: by company division, by geographical location, by role, or anything
else. (If you take the extra step to integrate the Access Control service together with Active
Directory Federated Services or any other custom authentication and authorization system, you
can integrate your connected application together with your pre-existing authorization system.)
Discovering Services
By default, services registered with the Service Bus are private. However, you can configure the
Service Bus to make your endpoints public when you register them. The Service Bus exposes
public endpoints in a registry published in an ATOM 1.0 feed that callers can discover by
browsing the root namespace URI in a Web browser. For more information about how to declare
124
that a registered endpoint is to be published as part of the namespace ATOM feed, see How to:
Publish a Service to the Service Bus Registry.
125
Overview of Service Bus Messaging Patterns
This section contains information about the different types of messaging patterns supported by
the Windows Azure Service Bus.
In This Section
Relayed and Brokered Messaging
Describes the new “brokered” messaging features and how they differ from the relayed
messaging pattern of earlier Service Bus releases.
Relayed Messaging
The central component of the Service Bus is a centralized (but highly load-balanced) relay
service that supports a variety of different transport protocols and Web services standards. This
includes SOAP, WS-*, and even REST. The relay service provides a variety of different relay
connectivity options and can even help negotiate direct peer-to-peer connections when it is
possible. The Service Bus is optimized for .NET developers who use the Windows
Communication Foundation (WCF), both with regard to performance and usability, and provides
full access to its relay service through SOAP and REST interfaces. This makes it possible for any
SOAP or REST programming environment to integrate with it.
The relay service supports traditional one-way messaging, request/response messaging, and
peer-to-peer messaging. It also supports event distribution at Internet-scope to enable
publish/subscribe scenarios and bi-directional socket communication for increased point-to-point
efficiency. In the relayed messaging pattern, an on-premise service connects to the relay service
through an outbound port and creates a bi-directional socket for communication tied to a
126
particular rendezvous address. The client can then communicate with the on-premises service by
sending messages to the relay service targeting the rendezvous address. The relay service will
then “relay” messages to the on-premises service through the bi-directional socket already in
place. The client does not need a direct connection to the on-premises service nor is it required to
know where the service resides, and the on-premises service does not need any inbound ports
open on the firewall.
You must initiate the connection between your on-premise service and the relay service, using a
suite of WCF “relay” bindings. Behind the scenes, the relay bindings map to new transport
binding elements designed to create WCF channel components that integrate with the Service
Bus in the cloud.
Relayed messaging provides many benefits, but requires the server and client to both be online
at the same time in order to send and receive messages. This is not optimal for HTTP-style
communication, in which the requests may not be typically long lived, nor for clients that connect
only occasionally, such as browsers, mobile applications, and so on. Brokered messaging
supports decoupled communication, and has its own advantages; clients and servers can
connect when needed and perform their operations in an asynchronous manner.
Brokered Messaging
In contrast to the relayed messaging scheme, brokered messaging can be thought of as
asynchronous, or “temporally decoupled.” Producers (senders) and consumers (receivers) do not
have to be online at the same time. The messaging infrastructure reliably stores messages until
the consuming party is ready to receive them. This allows the components of the distributed
application to be disconnected, either voluntarily; for example, for maintenance, or due to a
component crash, without affecting the whole system. Furthermore, the receiving application may
only have to come online during certain times of the day, such as an inventory management
system that only is required to run at the end of the business day.
The core components of theService Bus brokered messaging infrastructure are Queues, Topics,
and Subscriptions. These components enable new asynchronous messaging scenarios, such as
temporal decoupling, publish/subscribe, and load balancing. For more information about these
structures, see the next section.
As with the relayed messaging infrastructure, the brokered messaging capability is provided for
WCF and .NET Framework programmers and also via REST.
127
There are three messaging patterns that form the core of the new brokered messaging
capabilities in the Service Bus: Queues, Topics/Subscriptions, and Rules/Actions.
Queues
Queues offer First In, First Out (FIFO) message delivery to one or more competing consumers.
That is, messages are typically expected to be received and processed by the receivers in the
temporal order in which they were added to the queue, and each message is received and
processed by only one message consumer. A key benefit of using queues is to achieve “temporal
decoupling” of application components. In other words, the producers (senders) and consumers
(receivers) do not have to be sending and receiving messages at the same time, because
messages are stored durably in the queue. Furthermore, the producer does not have to wait for a
reply from the consumer in order to continue to process and send messages.
A related benefit is “load leveling,” which enables producers and consumers to send and receive
messages at different rates. In many applications, the system load varies over time; however, the
processing time required for each unit of work is typically constant. Intermediating message
producers and consumers with a queue means that the consuming application only has to be
provisioned to be able to handle average load instead of peak load. The depth of the queue will
grow and contract as the incoming load varies. This directly saves money with regard to the
amount of infrastructure required to service the application load. As the load increases, more
worker processes can be added to read from the queue. Each message is processed by only one
of the worker processes. Furthermore, this pull-based load balancing allows for optimum use of
the worker computers even if the worker computers differ with regard to processing power, as
they will pull messages at their own maximum rate. This pattern is often termed the “competing
consumer” pattern.
Using queues to intermediate between message producers and consumers provides an inherent
loose coupling between the components. Because producers and consumers are not aware of
each other, a consumer can be upgraded without having any effect on the producer.
Creating a queue is a multi-step process. Management operations for Service Bus messaging
entities (both queues and topics) are performed via the
Microsoft.ServiceBus.NamespaceManager class, which is constructed by supplying the base
address of the Service Bus namespace and the user credentials.
Microsoft.ServiceBus.NamespaceManager provides methods to create, enumerate and delete
messaging entities. After creating a
Microsoft.ServiceBus.Description.SharedSecretCredential object from the issuer name and
shared key, and a service namespace management object, you can use the
Microsoft.ServiceBus.NamespaceManager.CreateQueue(Microsoft.ServiceBus.Messaging.
QueueDescription) method to create the queue. For example:
// Create management credentials
128
namespaceManager namespaceClient = new
namespaceManager(ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace,
string.Empty), credentials);
You can then create a queue object and a messaging factory with the Service Bus URI as an
argument. For example:
QueueDescription myQueue;
myQueue = namespaceClient.CreateQueue("TestQueue");
MessagingFactory factory =
MessagingFactory.Create(ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace,
string.Empty), credentials);
You can then send messages to the queue. For example, if you have a list of brokered messages
called MessageList, the code would appear similar to the following:
for (int count = 0; count < 6; count++)
issue.Label = issue.Properties["IssueTitle"].ToString();
myQueueClient.Send(issue);
message.Complete();
Thread.Sleep(1000);
129
the message as being consumed, when the application restarts and begins consuming messages
again, it will have missed the message that was consumed prior to the crash.
In Microsoft.ServiceBus.Messaging.ReceiveMode.PeekLock mode, the receive operation
becomes two-stage, which makes it possible to support applications that cannot tolerate missing
messages. When the Service Bus receives the request, it finds the next message to be
consumed, locks it to prevent other consumers from receiving it, and then returns it to the
application. After the application finishes processing the message (or stores it reliably for future
processing), it completes the second stage of the receive process by calling
Microsoft.ServiceBus.Messaging.BrokeredMessage.Complete on the received message.
When the Service Bus sees the
Microsoft.ServiceBus.Messaging.BrokeredMessage.Complete, it will mark the message as
being consumed.
If the application is unable to process the message for some reason, it can call the
Microsoft.ServiceBus.Messaging.BrokeredMessage.Abandon method on the received
message (instead of Microsoft.ServiceBus.Messaging.BrokeredMessage.Complete). This will
cause the Service Bus to unlock the message and make it available to be received again, either
by the same consumer or by another completing consumer. Secondly, there is a timeout
associated with the lock and if the application fails to process the message before the lock
timeout expires (for example, if the application crashes), then Service Bus will unlock the
message and make it available to be received again.
Note that in the event that the application crashes after processing the message, but before the
Microsoft.ServiceBus.Messaging.BrokeredMessage.Complete request was issued, the
message will be redelivered to the application when it restarts. This is often called At Least Once
processing; that is, each message will be processed at least once but in certain situations the
same message may be redelivered. If the scenario cannot tolerate duplicate processing, then
additional logic is required in the application to detect duplicates which can be achieved based
upon the MessageId property of the message which will remain constant across delivery
attempts. This is known as Exactly Once processing.
For more information and a working example of how to create and send messages to and from
queues, see the Service Bus Brokered Messaging .NET Tutorial.
130
topic. Messages are received from a subscription in the identical way as they are received from a
queue.
By way of comparison, the message sending functionality of a queue maps directly to a topic and
its message receiving functionality to a subscription. Among other things, this means that
subscriptions support the same patterns described earlier in this section with regard to queues:
competing consumer, temporal decoupling, load leveling and load balancing.
Creating a topic is a process similar to creating a queue, as shown in the example in the previous
section. Create the service URI, and then use the Microsoft.ServiceBus.NamespaceManager
class to create the namespace client. You can then create a topic using the
Microsoft.ServiceBus.NamespaceManager.CreateTopic(System.String) method. For
example:
TopicDescription dataCollectionTopic =
namespaceClient.CreateTopic("DataCollectionTopic");
Using the message sender, you can send and receive messages to and from the topic, as shown
in the previous section. For example:
foreach (BrokeredMessage message in messageList)
myTopicClient.Send(message);
Console.WriteLine(
131
SubscriptionClient agentSubscriptionClient =
factory.CreateSubscriptionClient("IssueTrackingTopic", "Inventory",
ReceiveMode.PeekLock);
SubscriptionClient auditSubscriptionClient =
factory.CreateSubscriptionClient("IssueTrackingTopic", "Dashboard",
ReceiveMode.ReceiveAndDelete);
message.Complete();
Important
As noted in the topic How to: Publish a Service to the Service Bus Registry, you can use
Microsoft.ServiceBus.ServiceRegistrySettings to indicate whether you want your
service to be discoverable on the Service Bus. If your service is private, then only
individuals that know the specific URI can connect. If it is public, then anyone can
navigate the Service Bus hierarchy and find your listener. However, queues, topics, and
subscriptions cannot be exposed via the service registry.
132
to the virtual subscription queue. This is accomplished using subscription filters. Such
modifications are called Filter Actions. When a subscription is created, you can supply a filter
expression that can operate over the properties of the message, both the system properties (for
example, Label) and the application properties, such as StoreName in the previous example.
The SQL filter expression is optional in this case; without a SQL filter expression, any filter action
defined on a subscription will be performed on all the messages for that subscription.
Using the previous example, to filter messages coming only from Store1, you would create the
Dashboard subscription as follows:
namespaceManager.CreateSubscription(("Dashboard", new SqlFilter("StoreName = 'Store1'");
With this subscription filter in place, only messages that have the StoreName property set to
Store1 will be copied to the virtual queue for the Dashboard subscription.
For more information about possible filter values, see the documentation for the
Microsoft.ServiceBus.Messaging.SqlFilter and
Microsoft.ServiceBus.Messaging.SqlRuleAction classes. Also, see the
AdvancedFiltersSample in the Windows Azure SDK.
See Also
Service Bus Brokered Messaging .NET Tutorial
133
Naming System
The root of the Service Bus naming system is resolvable through traditional DNS techniques. The
naming system relies on host-independent criteria – specifically the service namespace – to
distinguish between different domains of control in the naming system. Service namespace
owners control the names within their respective service namespaces.
You project Service Bus names onto URIs as follows:
[scheme]://[service-namespace].servicebus.windows.net/[name1]/[name2]/...
The Service Bus supports three URI schemes: “sb”, “http”, and “https”. You use “http” and “https”
for all HTTP-based endpoints, and the “sb” scheme for all other TCP-based endpoints. The
[service-namespace] part of the host name identifies a unique naming tree in the complete
Service Bus namespace, which is controlled by the service namespace owner.
Note
In the current release, nesting in the URI naming scheme is not supported. For example,
topics and queues cannot be nested under each other. You cannot create a topic at
https://contoso.servicebus.windows.net/HumanResources/Topic1, then a queue at its
child location: https://contoso.servicebus.windows.net/HumanResources/Topic1/Queue1.
Conversely, you cannot create a queue at a location such as
https://contoso.servicebus.windows.net/HumanResources/Queue1, then a topic at its child
location: https://contoso.servicebus.windows.net/HumanResources/Queue1/Topic1.
Similarly, a relay endpoint (for example, an endpoint for
Microsoft.ServiceBus.NetTcpRelayBinding, any Http relay binding, or a message
buffer) and a messaging endpoint (for example, a queue or topic) cannot be nested under
each other. You cannot have a messaging endpoint at
https://contoso.servicebus.windows.net/HumanResources/Queue1 and a relay endpoint at
https://contoso.servicebus.windows.net/HumanResources/Queue1/Relay1.
Registry
The Service Bus provides a service registry for publishing and discovering service endpoint
references in a service namespace. Others can then discover the endpoints in a service
namespace by browsing to the service namespace base address and retrieving an Atom feed.
The service registry exposes the service namespace endpoints through a linked tree of Atom 1.0
feeds. You navigate the service registry by navigating the naming system via HTTP, browsing to
each level in the naming structure of the solution you want to inspect. When you browse to the
service namespace base HTTP address, you obtain the root Atom 1.0 feed describing the first
level of nested names. If you then browse to one of the nested names, you obtain another Atom
1.0 feed that describes the second level of nested names. This continues until you reach a leaf
name in the tree.
The Service Bus can publish endpoint information into the registry whenever you register new
endpoints. If you want a particular endpoint to be discoverable, you associate the
ServiceRegistrySettings behavior with the Windows Communication Foundation (WCF)
134
endpoint, setting its Microsoft.ServiceBus.ServiceRegistrySettings.DiscoveryMode property
to DiscoveryType.Public. The following code shows how to do this in the WCF host application:
class Program
host.Open();
settings.DiscoveryMode = DiscoveryType.Public;
foreach(ServiceEndpoint se in host.Description.Endpoints)
se.Behaviors.Add(settings);
Console.ReadLine();
host.Close();
With this behavior, the relay service automatically populates the service registry with information
about the endpoint in question.
Note
Queues, Topics, and Subscriptions are not discoverable in the service registry.
135
In This Section
Basic Service Bus Programming Lifecycle
This topic describes building a Windows Communication Foundation (WCF) Web
service, configuring it to register itself with the Service Bus, and creating a client that
calls the service by using the Service Bus.
See Also
Building Web Services that Trust ACS
136
1. Create a service namespace. This service namespace creates a named scope within which
the Service Bus creates resources to support Web services regardless of where they are
originally hosted or how. For more information, see Managing Service Bus Service
Namespaces.
2. Define the service contract, whether using WCF or using HTTP programming directly in the
.NET Framework (if you are using a message buffer). A contract specifies the signature of the
service, the data it exchanges, and other required inputs, behavior specifications, and object
invariants. For more information, see Designing a WCF Contract for the Service Bus.
3. Implement the contract. To implement a service contract, create a class that implements the
interface and specify custom runtime behavior.
4. Configure the service by specifying endpoint and other behavior information. For more
information, see Configuring a WCF Service to Register with the Service Bus.
5. Build and run the service. For more information, see Building a Service for the Service Bus.
6. Build and run the client application. For more information, see Building a Service Bus Client
Application.
As with any iterative, service-oriented software development, it may not always be appropriate to
follow the previous steps sequentially, or even start from step 1. For example, if you want to build
a client for a pre-existing service, you start at step 5. Or, if you are building a host service that
others will use, you can skip step 6.
The tasks required for creating a Windows Azure application for the Service
Bus
The basic tasks required to create a Windows Azure application that accesses the Service Bus
are the same as those in the topics described in Basic Service Bus Programming Lifecycle with
the sole exception that you must perform some tasks required to host your application in
Windows Azure. This is true whether your .NET application uses WCF and SOAP, the WCF
REST Programming Model, or .NET HTTP request programming directly.
To restate the complete lifecycle considering this:
1. Create the Windows Azure project and service namespace. The project and service
namespace contain the resources to support your application. For more information,
see Managing Service Bus Service Namespaces. You must also create a Windows Azure
Services account and project. For more information, see the Windows Azure documentation.
2. Define the service contract that is to be registered with the Service Bus. A contract specifies
the signature of the service and the data it exchanges. For more information, see Designing a
WCF Contract for the Service Bus. There are no additional steps at this point: Windows
137
Azure can act as the platform for an Windows Communication Foundation (WCF) interface
for both a service and client application that has no modifications to the interface.
3. Implement the service contract. To implement a contract, create the class whose methods
define the operations. As with the previous step, there is nothing specific for Windows Azure
to do at this point: Windows Azure is the host for a Web service that has no additional
modifications to the interface implementation.
4. Configure the service by specifying endpoint information and other behavior information. For
more information, see Configuring a WCF Service to Register with the Service Bus. In
addition, you must configure the Windows Azure service or client to use full trust
authentication. You must also make sure that the Service Bus assembly is uploaded to
Windows Azure. For more information, see How to: Configure a Windows Azure-Hosted
Service Bus Service or Client Application.
5. Create and run the service. For more information, see How to: Host a Service on Windows
Azure that Accesses the Service Bus. If your service is running locally (but connecting to a
Windows Azure-hosted client), there are no additional steps to perform.
6. Create and build the client application. If the client application is running on the local
computer, it requires no additional steps.
Depending upon the state of your application, you may not have to perform all these steps, or in
this sequence. For example, if you want to build a client for a pre-existing service, you can start at
step 5. Or, if you are building a service that others will use, you can skip step 6.
Note
Using message buffers is still supported, but future REST-style applications are advised
to use queues, topics, and subscriptions – depending on the specific need. For more
information on using queues, topics, and subscriptions in a REST-style application, see
the Service Bus Brokered Messaging REST Tutorial.
138
Creating a REST-based Application that uses the Service Bus
The basic tasks required to create an application that accesses the Service Bus using the REST
architecture model are as follows:
1. Create the Service Bus and Service Bus Access Control projects and the service
namespace. The project and service namespace contain the resources to support your
application. For more information, seeCreating a .NET Services Account. Both styles of
REST applications (REST applications that register Web service endpoints and those that
only use the message buffer) must have a Windows Azure Service Bus project and
namespace created by using the Service Bus Web portal: The former because it is a full
Service Bus application; the latter because the message buffer is one of the resources
created when you create a service namespace. The project also helps provide security and
authentication, through the Access Control service. For more information, see Building
Applications that Use Access Control Services.
2. Define the Service Bus contract. For more information, see Designing a WCF Contract for the
Service Bus. The main difference between using the message buffer and registering a
service endpoint is that if you are creating and registering a service endpoint that supports
the REST protocol, you must apply WCF attributes to your interface that map to the HTTP
verbs GET, PUT, DELETE, and UPDATE. For For more information, seeHow to: Expose a
REST-based Web Service Through the Service Bus. If you are only using the message
buffer, you do not have to define a REST interface: the message buffer itself is exposed
through a REST interface, which means there is no additional interface necessary.
3. If you are registering a REST-based service endpoint, you must implement the contract in the
previous step. The important point here is that the information passed through the interface
must be in a format that is transmittable by a REST-style service, for example, a stream. As
with the previous step, if you are only using the message buffer without additional support
from the .NET Framework, you do not have to implement any form of service contract: the
REST-based contract is already implemented and exposed by the message buffer.
4. Configure the service by specifying endpoint information and other behavior information. For
more information, seeConfiguring a WCF Service to Register with the Service Bus. For a full
Service Bus application that supports the REST protocol, the main difference is that the
application must use a binding that supports the REST protocol, such as
Microsoft.ServiceBus.WebHttpRelayBinding. However, other than that restriction, the
actual configuration is identical to any other WCF application that uses the Service Bus. In
contrast, an application that uses only the message buffer is much simpler. For more
information, seeHow to: Configure a Service Bus Message Buffer.
5. Build and run the service. For more information, seeBuilding a Service for the Service Bus.
For more information about creating an Service Bus service that supports the REST protocol,
see How to: Create a REST-based Service that Accesses the Service Bus. In contrast, when
non-WCF applications use the message buffer, the message buffer itself is the closest thing
to a “host”, although one of the REST applications must have requested creating the
message buffer. For more information, seeHow to: Create and Connect to a Service Bus
Message Buffer.
6. Build a client application. For more information, seeBuilding a Service Bus Client Application.
For a message buffer application, when the message buffer is created, any application that
connects to the message buffer (including the application that created the buffer) can send
139
and receive information: there are no host or client applications. For more information,
seeHow to: Send Messages to a Service Bus Message Buffer and How to: Retrieve a
Message from a Service Bus Message Buffer.
As with WCF applications, some scenarios do not start at the first step. For example, if you want
to build a client for a pre-existing service, you can start at step 5 (this would be the case for an
application that uses only the message buffer). Or, if you are building a host service that others
will use, you can skip step 6.
Basic Lifecycle
The basic lifecycle is as follows, and is completely implemented in a simple example in
the Service Bus Brokered Messaging REST Tutorial.
1. Use your service namespace, issuer name, and issuer key to contact the Windows Azure
Access Control service to obtain a Simple Web Token (SWT). You use the SWT to gain
access to your Service Bus service namespace resources.
2. Create the resources you want to use. For example, you might create a queue or a topic. If a
topic in which you are interested already exists, you can create a subscription to that topic,
add a filter, and so on.
3. Send messages to a queue or a topic.
4. Retrieve messages from a queue or a subscription.
5. If needed, delete the queue, topic, or subscription whose resources you want to enable the
Service Bus to reclaim.
See Also
Relayed and Brokered Messaging
Queues, Topics, and Subscriptions
Service Bus Brokered Messaging .NET Tutorial
140
Service Bus Authentication and Authorization with
the Access Control Service
The authorization of Windows Azure Service Bus operations, meaning the act of deciding
whether an operation may or may not be performed within the current security context, is a
cooperative effort between the Windows Azure Access Control Service (ACS) and the Service
Bus.
141
user’s identity as input. That token is then handed to Access Control, which evaluates it, runs the
rules, and emits the token for the relying party.
142
When the request arrives at Access Control, Access Controlwill match the realm URI to relying
party definitions by means of a ‘longest prefix match’, which means that the relying party whose
‘Realm URI’ address is the longest available prefix of the address that the token is requested for,
the relying party definition, and its associated rule definitions are selected and run. The default
‘ServiceBus’ relying party definition is scoped to the entirety of the corresponding Service
Bus service namespace, meaning that its Realm URI, corresponding to the Service Bus service
namespace root address, is a prefix to all possible addresses on a Service Bus service
namespace. As such, the rule definitions enabled on this relying party definition grant full access
across the entire Service Bus service namespace.
The way to create a scoped set of authorization rules for a queue residing at, for example,
https://tenant.servicebus.windows.net/my/test, is to create a new relying party definition, providing
the address of the queue or a prefix of that address as the Realm URI of the new definition, either
through the Access Control portal or the Access Control management API. On the portal, the
steps are:
• Under Relying Party Applications click Add.
• Enter some display name, for example MyTest.
• Enter http://tenant.servicebus.windows.net/my/test as the Realm URI for the scope.
• Choose SWT as the token format.
• Set Encryption Policy to None.
• Set Token lifetime to 1200 seconds.
• Click Save.
The result is a relying party definition that is exclusive to this address. Because its Realm URI is a
suffix of the built-in ‘ServiceBus’ relying party definition, the definition automatically inherits the
correct signing keys so that the Service Bus trusts tokens issued based on the new definition.
However, since there are no associated rules for new the relying party definition, so far, nobody
will be able to access the queue, not even the “owner”, because there is no automatic implicit
inheritance of rules between relying party definitions even if they form a hierarchy.
After creating the new definition, there will be a “Default Rule Group for <displayname>” in the
Rule Groups section of the Access Control portal. This new group is empty by default. In order to
permit access to the queue, rules need to be added to the group, which is explained in the
following section. Alternatively, an already existing rule group with rules can be enabled for the
relying party definition. Each rule group can be seen as a separate access control list that can be
enabled anywhere in the relaying party hierarchy. To enable file-system like inheritance, for
example to inherit the default rules of the Service Bus service namespace root, the corresponding
“Default Rule Group for ServiceBus” and any other rule group can simply be enabled on the
relying party definition – which requires checking the right box in the ‘Rule groups’ section of the
Relying Party definition on the portal. For cases in which a common set of access rules should be
applied across a number of resources, for example common rules for a set of parallel resources
such as sibling queues at http://tenant.servicebus.windows.net/my/test and
http://tenant.servicebus.windows.net/my/zoo, the relying party definition can also be scoped to
the shared service namespace branch, such as http://tenant.servicebus.windows.net/my.
143
In other cases, scenarios may call for managing access control differently for aspects of the same
Service Bus entity, such as different permissions on different subscriptions of a topic. In these
cases it is possible to create a relying party definition scoped to a particular subscription name,
such as http://tenant.servicebus.windows.net/my/test/subscriptions/sub1/, and have that definition
hold the rules applying only to the particular named subscription.
Defining Rules
Rules are defined in rule groups and generally map an input claim to an output claim. All rules in
a group yield a single combined result, so if there are three matching rules for a given input claim
set that yield three distinct output claims, the issued authorization token will contain all three
claims. For the Service Bus, the three permission claims are ‘Send’ for all send operations,
‘Listen’ to open up listeners or receive messages, and ‘Manage’ to observe or manage the state
of the Service Bus tenant. To be precise, ‘Send’, ‘Listen’, and ‘Manage’ are the permitted values
of the claim-type ‘net.windows.servicebus.action’. Creating a rule for the Service Bus requires
mapping an input claim, such as the nameidentifier of a service identity, to the desired permission
claim. To grant the service identity “contoso” the permission to ‘Send’ on a queue, the rule
definition would therefore map the issuer’s nameidentifier claim with the value “contoso” to a
custom output claim of type ‘net.windows.servicebus.action’ with a value of ‘Send’. Granting the
service identity all three permission claims requires three distinct rules. The goal of having just
three permission claims is to limit the complexity of defining rules. The table below shows how the
permission claims map to concrete operations on Service Bus entities:
Service Registry
Relay
Queue
144
Operation Claim Required Claim Scope
description Send
Topic
Get the topic description Manage or Send Any valid topic address
Subscription
145
Operation Claim Required Claim Scope
receiving the message
in peek-lock mode
Rule
146
Microsoft.ServiceBus.TransportClientEndpointBehavior APIs accept
Microsoft.ServiceBus.TokenProvider instances. The token provider is called as tokens are
required, which includes scenarios where a long-lived connection needs to acquire a new token
once the existing token has passed its expiration (which defaults to 1200 seconds). Federation
scenarios that require user interaction do require implementation of a custom token provider.
As an example, a custom token provider to enable a particular Facebook user to send messages
to a particular queue will have to present the user, via Access Control, with the appropriate
Facebook UI to establish the Facebook identity, redirect via Access Control to trade the
Facebook token for an Access Control token for the Service Bus, and then extract the Access
Control token as the request gets redirected to the local application. The Service Bus Codeplex
site will contain a growing collection of token provider examples for customization.
BasicHttpBinding BasicHttpRelayBinding
WebHttpBinding WebHttpRelayBinding
WS2007HttpBinding WS2007HttpRelayBinding
NetTcpBinding NetTcpRelayBinding
N/A NetOnewayRelayBinding
N/A NetEventRelayBinding
The relay bindings work in a similar manner to the standard WCF bindings. For example, they
support the different WCF message versions (SOAP 1.1, SOAP 1.2, and None), the various WS-*
security scenarios, reliable messaging, streaming, metadata exchange, the Web programming
model (e.g., [WebGet] and [WebInvoke]), and many more standard WCF features. There are only
a few WCF features not supported by design including atomic transaction flow and transport level
authentication.
147
If you are familiar with how WCF works, you might be interested to know how the new bindings
(shown earlier in this topic) map to the underlying WCF transport binding elements. The following
table specifies the transport binding element for each relay binding. As you can see, the SDK
includes several new WCF transport binding elements including RelayedHttpBindingElement,
RelayedHttpsBindingElement, TcpRelayTransportBindingElement, and
RelayedOnewayTransportBindingElement.
BasicHttpRelayBinding RelayedHttp(s)BindingElement
WebHttpRelayBinding RelayedHttp(s)BindingElement
WS2007HttpRelayBinding RelayedHttp(s)BindingElement
NetTcpRelayBinding TcpRelayTransportBindingElement
NetOnewayRelayBinding RelayedOnewayTransportBindingElement
NetEventRelayBinding RelayedOnewayTransportBindingElement
These new WCF primitives are ultimately what provide the low-level channel integration with the
relay service behind the scenes, but those details are hidden from view behind the binding. The
following sections discuss the details of the main WCF relay bindings and show how to use them.
NetMessagingBinding
The Microsoft.ServiceBus.Messaging.NetMessagingBinding binding can be used by WCF-
enabled applications to send and receive messages through queues, topics and subscriptions.
For more information, see NetMessagingBinding.
NetOnewayRelayBinding
Microsoft.ServiceBus.NetOnewayRelayBinding is the most constrained of the all the relay
bindings, because it only supports one-way messages. However, it is also specifically optimized
for that scenario. By default, the Microsoft.ServiceBus.NetOnewayRelayBinding binding uses
SOAP 1.2 over TCP together with a binary encoding of the messages, although these
communication settings are configurable through standard binding configuration techniques.
Services that use this binding must always use the “sb” protocol scheme.
When using this binding in the default configuration, the on-premise WCF service attempts to
establish an outbound connection with the relay service in order to create a bidirectional socket.
In this case, it always creates a secure TCP/SSL connection through outbound port 828. During
the connection process the WCF service authenticates (by supplying a token acquired from
Access Control), specifies a name on which to listen in the relay service, and tells the relay
service what type of listener to create. When a WCF client uses this binding in the default
configuration, it creates a TCP connection with the relay via port 808 (TCP) or 828 (TCP/SSL),
148
depending on the binding configuration. During the connection process it must authenticate with
the relay by supplying a token acquired from Access Control. Once the client has successfully
connected, it can start to send one-way messages to the Service Bus to be “relayed” to the on-
premises service through its TCP connection
If you set the Microsoft.ServiceBus.NetOnewayRelayBinding binding security mode property
to Transport, the channel will require SSL protection. In this case, all traffic sent to and from the
relay service will be protected via SSL; however, it is important to realize that the message will
pass through the relay service in the clear. If you want to ensure full privacy, you should use the
Message security mode, in which case you can encrypt everything except the addressing
information in the message passing through the relay service.
The Microsoft.ServiceBus.NetOnewayRelayBinding binding requires all operations on the
service contract to be marked as one-way operations (IsOneWay=true). Assuming that’s the case,
to use this WCF binding, specify it on your endpoint definitions and supply the necessary
credentials.
ConnectivityMode Description
Tcp Services create TCP connections with the relay service through port
828 (SSL).
Http Services create an HTTP connection with the relay service making it
easier to work around TCP port constraints.
AutoDetect (Default) This mode automatically selects between the Tcp and Http modes
based on an auto-detection mechanism that probes whether either
connectivity option is available for the current network environment and
prefers Tcp.
AutoDetect is the default mode, which means the relay bindings will automatically determine
whether to use TCP or HTTP for connecting the on-premises service to the relay service. If TCP
is possible on the given network configuration, it will use that mode by default (that is, it attempts
to use TCP by sending a ping message to a connection-detecting URL). If the TCP connection
149
fails, it automatically switches to the HTTP mode. Hence, most of the time, you do not have to set
this property explicitly because the default “auto detect” behavior determines the behavior for you.
The only time that you have to set this property explicitly is when you want to force either TCP or
HTTP.
You can set the connectivity mode at the AppDomain-level through the static
Microsoft.ServiceBus.ServiceBusEnvironment class. It provides a
Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity property in which you
can specify one of the three ConnectivityMode values shown earlier in this section. The
following code illustrates how to modify an application to use the HTTP connectivity mode:
...
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
host.Open();
...
The system connectivity mode setting takes effect on all of the relay bindings.
NetEventRelayBinding
Microsoft.ServiceBus.NetEventRelayBinding is very similar to the
Microsoft.ServiceBus.NetOnewayRelayBinding binding, in the way it is implemented. The
binding defaults and security options are identical to those for
Microsoft.ServiceBus.NetOnewayRelayBinding. In addition, the mechanics around how
clients/services interact with the relay service are basically the same. In fact, the
Microsoft.ServiceBus.NetEventRelayBinding class actually derives from the
Microsoft.ServiceBus.NetOnewayRelayBinding class.
The main difference in the Microsoft.ServiceBus.NetEventRelayBinding binding is that it lets
you register multiple WCF services with the same Service Bus address. When a client sends a
message to such an address, the relay service multicasts the message to all on-premise WCF
services currently subscribed to that address.
The Microsoft.ServiceBus.NetEventRelayBinding binding supports the same
Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity options as
Microsoft.ServiceBus.NetEventRelayBinding. When you configure the
Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity property on the
Microsoft.ServiceBus.ServiceBusEnvironment class, it takes effect for all endpoints. Hence,
you can use the aggressive HTTP connectivity mode for all your on-premise
Microsoft.ServiceBus.NetEventRelayBinding endpoints if they are hosted in a locked-down
network environment that blocks outbound TCP connections.
NetTcpRelayBinding
The Microsoft.ServiceBus.NetTcpRelayBinding binding supports two-way messaging
semantics and is very closely aligned with the standard WCF NetTcpBinding – the key
150
difference is that Microsoft.ServiceBus.NetTcpRelayBinding creates a publicly-reachable TCP
endpoint in the relay service.
By default, the Microsoft.ServiceBus.NetTcpRelayBinding binding supports SOAP 1.2 over
TCP and it uses binary serialization for efficiency. Although its configuration is very similar to that
of the NetTcpBinding, their underlying TCP socket layers are different and are therefore not
directly compatible with each other. This means that client applications will also have to be
configured to use Microsoft.ServiceBus.NetTcpRelayBinding in order to integrate.
First, the on-premises WCF service establishes a secure outbound TCP connection with the relay
service. During the process, it must authenticate, specify an address to listen on, and specify
what type of listener to create in the relay. Up to this point, it is very similar to the
Microsoft.ServiceBus.NetOnewayRelayBinding binding. When an incoming message arrives
on one of the front nodes, a control message is then routed down to the on-premises WCF
service indicating how to create a rendezvous connection back with the client front-end node.
This establishes a direct socket-to-socket forwarder for relaying TCP messages.
The Microsoft.ServiceBus.NetTcpRelayBinding binding supports two connection modes (see
Microsoft.ServiceBus.TcpRelayConnectionMode) that control how the client and service
communicate with each other through the relay service (see the following table).
TcpConnectionMode Description
Microsoft.ServiceBus. All communication is relayed through the relay service. The SSL-
TcpRelayConnectionM protected control connection is used to negotiate a relayed end-to-end
ode.Relayed (default) socket connection that all communication flows through. Once the
connection is established the relay service behaves as a socket
forwarder proxy relaying a bi-directional byte stream.
Relayed mode is the default, while Hybrid mode instructs the relay service to establish a direct
connection between the client and service applications. Therefore, no data has to pass through
the relay. It is considered a “hybrid” mode because it starts by relaying information through the
relay while it attempts to upgrade to a direct connection. If successful, it will switch over to a direct
151
connection without any data loss. If it cannot establish a direct connection, it will continue to use
the relay service. The Microsoft.ServiceBus.NetTcpRelayBinding binding also supports the
Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity feature when you must
configure the on-premises service to connect to the relay service over HTTP. When you configure
the Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity property, it takes
effect for all endpoints. Hence, you can use the aggressive HTTP connectivity mode for all your
on-premise Microsoft.ServiceBus.NetTcpRelayBinding endpoints if they are being hosted in a
locked-down network environment that blocks outbound TCP connections.
152
Designing a WCF Contract for the Service Bus
The following topics describe how to design an Windows Communication Foundation (WCF)
service contract that can be registered to be available on at a Windows Azure Service Bus
endpoint.
In This Section
How to: Design a WCF Service Contract for use with the Service Bus
This topic describes how to create a SOAP-based WCF service contract that can be
configured to use the Service Bus.
How to: Expose a REST-based Web Service Through the Service Bus
This topic describes how to create a REST-based WCF service contract that can be
configured to use the Service Bus.
How to: Design a WCF Service Contract for use with the Service
Bus
After you have created your Windows Azure Service Bus project, you can start writing code. The
first step in writing the code is to define the interface that your service application uses to
communicate with the client application. This interface, known as a service contract, is almost
identical to a Windows Communication Foundation (WCF) contract: it defines the name of the
interface, and also to the methods and properties exposed by the interface. You can use WCF-
style attributes to add information to the contract, and you use the same syntax to do this. The
main difference is that the Service Bus is an extension of WCF. Therefore, you must also define a
channel to connect to the Service Bus. However, other extensions of WCF use a similar channel.
Therefore, the channel itself is not unique to the Service Bus. The following discussion is a brief
overview of creating an Service Bus contract.
As with WCF, both the service and client applications are required to have a copy of the contract
in their code. There are four ways this can occur:
1. Manually define the contract – this is the default, and is used most often when you are
developing the interface. A simplified process for doing this is shown later in this section. For
a complete discussion, see Designing Service Contracts in the WCF documentation.
153
2. Copy the contract from the service code – this is copying and pasting the contract from
the service code, or sharing in the project. This is accomplished when you have quick access
to the code, for example, when you are also the developer writing the client. Many of the
sample applications in the Windows Azure SDK share the same interface definition, because
both the client and service are in the same project.
3. Use the ServiceModel Metadata Utility Tool (scvutil.exe) – this is an application that you
point to an exposed metadata endpoint on a running service application. It returns a file that
contains the associated service contract. A simplified procedure for doing this is described
later in this section. For a complete discussion, see Accessing Services Using a WCF
Client and ServiceModel Metadata Utility Tool (Svcutil.exe) in the WCF documentation.
The main difference in using Svcutil.exe on an Service Bus application is that the URI passed
to the tool is on the Service Bus, instead of on the local host. Note that Svcutil.exe requires
the target service to have the appropriate metadata exposed. For more information, seeHow
to: Expose a Metadata Endpoint.
4. Add a service reference through Visual Studio – this is the UI version of Svcutil.exe, and
can be accessed through the Visual Studio environment. A simplified procedure for accessing
the Add Service Reference dialog box is shown later in this section. For more information,
seeHow to: Add, Update, or Remove a Service Reference in the Visual Studio
documentation. As stated previously, adding a service reference requires that the target
service expose the necessary information through a metadata endpoint.
2. Indicate which methods in the interface a client can invoke by applying the
System.ServiceModel.OperationContractAttribute attribute to them.
[ServiceContract]
public interface IMyContract
{
[OperationContract]
void Send(int count);
}
154
3. It best to explicitly define the name of your contract, and also to the namespace of your
application, when declaring the contract. Doing so prevents the infrastructure from using
the default name and namespace values. Note that this is not the service namespace: in
this case, it represents a unique identifier for your contract, and should contain some kind
of versioning information.
[ServiceContract(Name = "IMyContact", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/MyContractV1
")]
public interface IMyContract
{
[OperationContract]
void Send(int count);
}
4. Declare a channel that inherits from your interface and also to the IClientChannel
interface.
[ServiceContract(Name = "IMyContact", Namespace =
"http://samples.microsoft.com/ServiceModel/Relay/MyContractV1
")]
public interface IMyContract
{
[OperationContract]
void Send(int count);
}
155
If the target address has the appropriate metadata exposed, you will retrieve a file that
contains WCF client code that the client application can use to start the service
application.
Note
If you plan to develop an application that uses the message buffer, you do not have to
define an Service Bus contract: the message buffer is already exposed by using a REST
interface. For more information, seeWorking with a Service Bus Message Buffer.
156
GET [OperationContract, WebGet] or [OperationContract]
[WebGet]
PUT [OperationContract]
[WebInvoke(Method = “PUT”)]
DELETE [OperationContract]
[WebInvoke(Method = “DELETE”)]
POST [OperationContract]
[WebInvoke]
The following example shows how to tag an interface member as a REST-style GET
member.
public interface ImageContract
{
[OperationContract, WebGet]
Message GetImage();
}
3. If you are designing a service, implement the contract as a class elsewhere in your
project.
157
• The type of binding your application uses, which includes transport, security, and encoding
settings.
• The address at which the contract is available.
When using WCF you can set these properties in an WCF service or client application either
programmatically or in an App.config file. However, it is usually best to specify the binding and
address information declaratively in a configuration file, instead of imperatively in code unless
your specific scenario requires it. Defining endpoints in code is usually not practical because the
bindings and addresses for a deployed service are typically different from those used as the
service is being developed. More generally, keeping the binding and addressing information out
of the code enables them to change without having to recompile or redeploy the application.
Note that if you do not have the Windows Azure SDK installed on a particular computer the
Machine.config file does not have the necessary extensions that enable the .NET run time to
interpret Service Bus-specific information. While there are workarounds for this situation, it is
usually easier to define your configuration in the code. (For more information about working to
enable application configuration files, see the RelayConfigurationInstaller.exe Tool).
The following list contains the general scenarios for configuring an Service Bus application. For
additional information about how to configure a WCF application, see Configuring Services in
the WCF documentation.
• Basic Application
This type of application is a WCF SOAP-based application that is configured to use the
Service Bus as a secured relay to connect to other applications. The only differences
required to use the Service Bus are the type of binding and the endpoint address. WCF
applications that use the Service Bus use one of the relay bindings available in the Windows
Azure SDK, bindings which have authentication and transport elements not present in the
standard WCF bindings. Similarly, the endpoint address that is used for the service endpoint
is an Service Bus URI based on the registered Service Bus namespace name (and may also
have a different protocol scheme), whereas a regular WCF application uses an address
based on the local host. Because these are the only two configuration differences, you can
often – but not always – just reconfigure a currently existing WCF application to expose its
services through the Service Bus
• REST-based Application
The topics in this documentation describe are two types of REST applications: those that use
the WCF Web programming model and the Windows Azure SDK, and one that does not.
However, the topics in this section only describe REST applications that use the Windows
Azure SDK as a programming foundation. (REST-based applications that do not use the
Windows Azure SDK can use the message buffer as a location to and from which to send
and receive messages. For more information about about REST applications that use the
message buffer, see Working with a Service Bus Message Buffer.)
If your application does use the Windows Azure SDK, you can configure your application just
as any other REST-based WCF service: you must use a relay binding that supports HTTP,
such as Microsoft.ServiceBus.WebHttpRelayBinding or
Microsoft.ServiceBus.WS2007HttpRelayBinding, and you must apply the appropriate
158
WCF attributes to your interface, and confirm that your implementation can send and receive
HTTP messages and events. For more information, seeDesigning a WCF Contract for the
Service Bus.
• Windows Azure-hosted Application
Because Windows Azure does not have the Windows Azure SDK installed it does not have
the information necessary in its Machine.config file to identify configuration elements specific
to Service Bus. If you must use an App.config file, you can include all of the necessary
information into an App.config file by using the RelayConfigurationInstaller.exe Tool.
However, whereas this enables you to use an App.config file together with Windows Azure,
you may encounter duplication issues on your development computer. Therefore, we
recommend that when you use Windows Azure, you configure your applications
programmatically.
In addition, you must set your Windows Azure worker or Web role to Full Trust – this is
required for all applications that use the Service Bus. This is not specified in the configuration
file, but in the ServiceDefinition.csdef file. For more information, seeHow to: Configure a
Windows Azure-Hosted Service Bus Service or Client Application.
In This Section
How to: Configure a Service Bus Service Programmatically
How to: Configure a Service Bus Service Using a Configuration File
How to: Configure a Service Bus Client Using Code
How to: Configure a Service Bus Client Using a Configuration File
How to: Configure a Windows Azure-Hosted Service Bus Service or Client Application
How to: Change the Connection Mode
Creating a Custom Service Bus Binding
Windows Azure Service Bus Quotas
Service Bus Port Settings
159
the Service Bus, usually in the form of a shared secret (that is, issuer name and secret) token.
However, the service also determines what type of authentication credentials the client
applications must use in order to connect to the service. By default, client authentication is set to
RelayClientAuthenticationType.RelayAccessToken, which means that the client must present
some form of authentication to the Service Bus. In the current version of Windows Azure, this is
always another shared secret token. In contrast, transport security determines whether it must
connect with some form of secure line. This is referred to as “end-to-end” security because it
covers the whole connection between the service, the Service Bus, and the client. In contrast,
client authentication covers only the required relationship to connect from the service to the
Service Bus. By default, the transport security is set to EndToEndSecurityMode.Transport. This
means that security is provided using some form of secure transport, such as HTTPS. It is
recommended that you keep the end-to-end security mode set to Transport unless you have a
compelling reason to change it, as doing this might reduce the security of your application. For
more information about security settings, see Securing and Authenticating a Service Bus
Connection
The following procedure describes how to configure an Service Bus service programmatically.
The prefix “sb” indicates that this URI uses the Service Bus schema. Other schemas
include HTTP or HTTPS.
2. Instantiate the host with the contract and URI.
host = new ServiceHost(typeof(EchoService), uri);
3. Declare and implement the type of authentication credentials to use.
string issuerName = "MY ISSUER NAME"
string issuerSecret = "MY SECRET";
TransportClientEndpointBehavior
sharedSecretServiceBusCredential = new
TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.CredentialType =
TransportClientCredentialType.SharedSecret;
sharedSecretServiceBusCredential.Credentials.SharedSecret.Iss
uerName = issuerName;
sharedSecretServiceBusCredential.Credentials.SharedSecret.Iss
160
uerSecret = issuerSecret;
All services are required to use authentication credentials to connect to the Service Bus.
Note that hard-coding the issuer name and secret into your code is not a secure practice.
For example, many of the samples in the Windows Azure SDK prompt the user for this
information.
4. Declare the type and instance of the contract.
ContractDescription contractDescription =
ContractDescription.GetContract(typeof(IEchoContract),
typeof(EchoService));
5. Add the contract description to the service endpoint.
ServiceEndpoint serviceEndPoint = new
ServiceEndpoint(contractDescription);
6. Add the URI to the service endpoint.
serviceEndPoint.Address = new EndpointAddress(uri);
7. Declare the type of binding to use for the endpoint.
serviceEndPoint.Binding = new NetTcpRelayBinding();
At this point you can declare the Authentication and EndToEndSecurity mode. This
particular example uses the default constructor, which sets the
Microsoft.ServiceBus.EndToEndSecurityMode to Transport and the
Microsoft.ServiceBus.RelayClientAuthenticationType to RelayAccessToken.
Therefore,, the following snippet is identical to the default constructor, except that it sets
those two parameters explicitly:
serviceEndPoint.Binding = new
NetTcpRelayBinding(EndToEndSecurityMode.Transport,
RelayClientAuthenticationType.RelayAccessToken);
8. Add the security credentials to the endpoint.
serviceEndpoint.Behaviors.Add(sharedSecretServiceBusCredentia
l);
These security credentials are required for all services to authenticate with the Service
Bus. Because we set the Microsoft.ServiceBus.RelayClientAuthenticationType to
RelayAccessToken (either by default or explicitly), any client applications are also
required to use the same type of authentication credentials.
9. Add the endpoint to the host.
host.Description.Endpoints.Add(serviceEndPoint);
You have now created the minimum configuration necessary for an Service Bus service
application. At this point, you can add more service-level or endpoint-level configurations,
as you would with any other WCF application. For more information about configuring a
WCF application, see Configuring Services in the WCF documentation. When you are
finished configuring your application, you can host and run your application. For more
161
information, seeBuilding a Service for the Service Bus.
Example
Description
The following example shows how to define configuration information programmatically. The main
difference is that all information is set programmatically; in the tutorial, some information not
specific to Windows Azure is stored in an App.config file.
Code
namespace AzureSample_WorkerRole
sharedSecretServiceBusCredential.CredentialType =
TransportClientCredentialType.SharedSecret;
sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName =
issuerName;
sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret =
issuerSecret;
162
ContractDescription contractDescription =
ContractDescription.GetContract(typeof(IEchoContract), typeof(EchoService));
serviceEndpoint.Behaviors.Add(sharedSecretServiceBusCredential);
host.Description.Endpoints.Add(serviceEndPoint);
host.Open();
while (true)
//Loop
host.Close();
base.Stop();
return RoleStatus.Healthy;
163
Comments
Note
The Service Bus uses the default configuration that you have specified in the App.config
file. Therefore, you do not have to directly reference the configuration in your code.
However, if you have multiple endpoints and bindings, you may want to explicitly state
which configuration to use, in order to avoid confusion.
The following procedure describes how to configure an Service Bus service by using an
App.config file.
164
To configure a Service Bus service application by using an App.config file
1. To configure the endpoint for the service that uses the contract with a specified binding,
create the App.config file. For example:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!-- Application Service -->
<service name="Microsoft.ServiceBus.Samples.EchoService">
<endpoint
contract="Microsoft.ServiceBus.Samples.IEchoContract"
binding="netTcpRelayBinding"
address="sb://MyCodeSample.ServiceBus.Microsoft.com/EchoServi
ce" />
</service>
</services>
</system.serviceModel>
</configuration>
Note the minimum parameters that are required to configure an endpoint: the service
name, the contract that implements the service, the type of binding used, and the
address. The service uses the default Transport and Authentication security
parameters. Therefore, they are not explicitly declared. The address is explicitly declared
here, although very often it is built programmatically using the URI type.
Once you have completed the steps that are required to configure an Service Bus
service, you can add more endpoint and service-level configurations. For more
information, seeConfiguring Services in the WCF documentation.
2. After you have finished configuring the service, you can host and run the application. For
more information, seeBuilding a Service for the Service Bus.
166
4. Apply the Service Bus credentials:
ChannelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusC
redential);
You are now finished configuring the client application. You can move on to implementing
the rest of the client application, in Building a Service Bus Client Application. Note that
this tutorial does use an App.config file; however, it is only to store name and password
information in a string, and is easily replaced by the code used in this procedure.
contract="Microsoft.ServiceBus.Samples.IEchoContract"
binding="netTcpRelayBinding"
bindingConfiguration="default"
167
behaviorConfiguration="sharedSecretEndpointBehavior"
address="" />
</client>
</system.serviceModel>
</configuration>
Similar to configuring a service application, the minimum parameters that you must have
to configure an endpoint are the contract that implements the service, and the type of
binding used. The address attribute is the Service Bus address. It can be specified
explicitly in the configuration file but is usually constructed programmatically using the
Microsoft.ServiceBus.ServiceBusEnvironment.CreateServiceUri(System.String,Sys
tem.String,System.String) method. This example also associates an endpoint behavior
with the client.
2. Define the endpoint behavior that contains the security settings.
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretEndpointBehavior">
<transportClientEndpointBehavior
credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="ISSUER_NAME"
issuerSecret="ISSUER_SECRET" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
In this example, for simplicity the security credentials are defined by using the issuer
name and secret in clear text. Note that this is an nonsecure programming practice: a
more secure process (and the process used by many samples in the Windows Azure
SDK) is to query the user for this information. Alternately, you could decide to encrypt the
App.config file to avoid exposing this information.
3. Define the binding that the client application is to use when it connects to the Service
Bus.
<bindings>
<!-- Application Binding -->
<netTcpRelayBinding>
168
<!-- Default Binding Configuration-->
<binding name="default" />
</binding>
</bindings>
4. You have finished configuring the client application through the App.config file. For more
information about creating a Service Bus client application, see Building a Service Bus
Client Application.
It is recommended that you add these extensions to the App.config files for your projects or
use the Relayconfiginstaller.exe tool in the SDK to add these bindings. For example:
<configuration>
<system.serviceModel>
<extensions>
169
<!-- Adding all known service bus extensions. You can remove the
ones you don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior"
type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement
, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpoint
BehaviorElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="serviceRegistrySettings"
type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettings
Element, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingT
ransportExtensionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="tcpRelayTransport"
type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElemen
t, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="httpRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpRelayTransportEleme
nt, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="httpsRelayTransport"
type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElem
ent, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<add name="onewayRelayTransport"
type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportE
lement, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
170
<bindingExtensions>
<add name="basicHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCo
llectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="webHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingColl
ectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ws2007HttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingC
ollectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingColle
ctionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netOnewayRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCo
llectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netEventRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCol
lectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netMessagingBinding"
type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingB
indingCollectionElement, Microsoft.ServiceBus, Version=1.5.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
</system.serviceModel>
</configuration>
171
This step is the standard process for adding a reference to an assembly.
2. In the Reference folder, right-click Microsoft.ServiceBus. Then click Properties.
3. In the Properties dialog, set Copy Local to True.
Doing so makes sure that the Microsoft.ServiceBus assembly will be available to your
application when it runs on Windows Azure.
<InputEndpoints>
<!-- Must use port 80 for http and port 443 for https when
running in the cloud -->
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</InputEndpoints>
</WebRole>
<WorkerRole name="WorkerRole" enableNativeCodeExecution="true">
</WorkerRole>
</ServiceDefinition>
172
Microsoft.ServiceBus.TcpRelayTransportBindingElement to define the
Microsoft.ServiceBus.NetTcpRelayBinding binding. Therefore,, you can set the connection
mode for a Microsoft.ServiceBus.NetTcpRelayBinding binding by setting the
Microsoft.ServiceBus.NetTcpRelayBindingBase.ConnectionMode property. You can do this
at any time in your application: the Service Bus will take the change and attempt to modify the
connection. As with most properties, you can decide to set the connection status in the
App.config file. Finally, the Service Bus exposes the current status of the connection through the
Microsoft.ServiceBus.IHybridConnectionStatus interface, which you can decide to implement.
The following topic describes how to determine or modify the mode of an Service Bus application.
Note that the netTcpRelayBinding tag does not specify the connection mode attribute.
By default, the connection mode used is Relayed.
2. Explicitly change the connection mode to Hybrid by adding the connectionMode field,
which is set to Hybrid.
<bindings>
<netTcpRelayBinding>
<binding name="default" connectionMode="Hybrid">
<security mode="None" />
</binding>
</netTcpRelayBinding>
</bindings>
173
To determine when the connection mode changes
1. Optionally, you might want to receive a notification when the connection between the
connected endpoints changes from a Relayed connection to a Hybrid connection.
channel.Open();
IHybridConnectionStatus hybridConnectionStatus =
channel.GetProperty<IHybridConnectionStatus>();
if (hybridConnectionStatus != null)
{
hybridConnectionStatus.ConnectionStateChanged += (o, e)
=>
{
Console.WriteLine("Connection state changed to:
{0}.", e.ConnectionState);
};
}
TcpRelayTransportBindingElement
The Microsoft.ServiceBus.TcpRelayTransportBindingElement element is closely aligned with
the WCF version, System.ServiceModel.Channels.TcpTransportBindingElement and is the
foundation for NetTcpRelayBinding.
174
Additional members Description
Service Bus and to the services listening through it.
This property controls whether clients of a service are
required to present a security token issued by the Access
Control service to the Service Bus service when it sends
messages. Services are always required to authenticate with
Access Control and present an authorization token to the
Service Bus. If the service assumes the responsibility of
authenticating/authorizing clients, it can opt out of the
integration between Access Control and Service Bus by
setting this property to
RelayClientAuthenticationType.None. The default value is
RelayClientAuthenticationType.RelayAccessToken.
HttpRelayTransportBindingElement
The Microsoft.ServiceBus.HttpRelayTransportBindingElement element is closely aligned with
the WCF version, System.ServiceModel.Channels.HttpTransportBindingElement and is the
foundation for all HTTP relay bindings that are configured to use unsecured HTTP
communication.
175
Additional members Description
HttpsRelayTransportBindingElement
The Microsoft.ServiceBus.HttpsRelayTransportBindingElement element derives from
HttpRelayTransportBindingElement and is the foundation for all HTTP Relay bindings that are
configured to use secured HTTPS communication.
OnewayRelayTransportBindingElement
The Microsoft.ServiceBus.OnewayRelayTransportBindingElement element is the foundation
for the Microsoft.ServiceBus.NetEventRelayBinding and
Microsoft.ServiceBus.NetOnewayRelayBinding bindings. As a TCP-based transport binding
element, it is similar to the WCF
System.ServiceModel.Channels.TcpTransportBindingElement element, but only supports
one-way communication.
176
Additional members Description
Service Bus. If the service assumes the responsibility of
authenticating and authorizing clients, it can opt out of the
integration between Access Control and Service Bus by
setting this property to
RelayClientAuthenticationType.None. The default value is
RelayClientAuthenticationType.RelayAccessToken.
no HTTPS
no 9350/HTTP
177
Microsoft.ServiceBus.NetOnewayRelayBinding yes 9351/HTTPS
(client)
no 9350/HTTP
no HTTP
no HTTP
178
• Microsoft.ServiceBus.TransportClientCredentialType.Unauthenticated, which enables
interaction with the service endpoint without any authentication behavior.
In the second case, the originating service itself typically applies some end-to-end security that
specifies message-level security (such as message encryption) and transport-level security (such
as Windows or NTLM). End-to-end conversation security follows the Windows Communication
Foundation (WCF) programming model, and is discussed more fully in the Securing Services
topic in the WCF documentation. Therefore, although the following topics contain a general
discussion of end-to-end security, they focus mainly on the features unique to a service
configured to use the Service Bus. For additional information about Service Bus authentication
and Access Control, see Building Applications that Use Access Control Services.
Every Service Bus relay binding has a security binding element – for example, the
Microsoft.ServiceBus.Configuration.NetTcpRelaySecurityElement performs the security
functions for the Microsoft.ServiceBus.NetTcpRelayBinding – that contains the following
security values that you can specify either programmatically or in a configuration file.
Mode
Short for end-to-end security mode, this value defines the security across the message
exchange through the Service Bus. The programmatic value depends on the specific
relay binding; for example, the Microsoft.ServiceBus.EndToEndSecurityMode
type supports the Microsoft.ServiceBus.NetTcpRelayBinding binding, and the
Microsoft.ServiceBus.EndToEndWebHttpSecurityMode value performs this
service together with the Microsoft.ServiceBus.WebHttpRelayBinding binding.
When used with the Microsoft.ServiceBus.NetTcpRelayBinding binding, this
property can be set to Microsoft.ServiceBus.EndToEndSecurityMode.None,
Microsoft.ServiceBus.EndToEndSecurityMode.Message,
Microsoft.ServiceBus.EndToEndSecurityMode.Transport, or
Microsoft.ServiceBus.EndToEndSecurityMode.TransportWithMessageCre
dential. The default is
Microsoft.ServiceBus.EndToEndSecurityMode.Transport, which means that
the transport-specific security settings are enabled. If you use any setting that includes
Microsoft.ServiceBus.EndToEndSecurityMode.Message or
Microsoft.ServiceBus.EndToEndSecurityMode.Transport, you will have to
set additional properties. In general, Mode value follows the standard WCF security
programming model.
Message
Defines security on a per-message basis if you set end-to-end message security to
Microsoft.ServiceBus.EndToEndSecurityMode.Message or
Microsoft.ServiceBus.EndToEndSecurityMode.TransportWithMessageCre
dential. Setting one of those values for the Mode property requires that this property
also be set to specify the type of credentials that are used, and also to the algorithm
that is used to help secure the credentials. As with Mode, the message security setting
follows the WCF programming model.
179
Transport
This property is a wrapper for security properties unique to a given binding’s transport
binding element. For example, the
Microsoft.ServiceBus.RelayedOnewayTransportSecurity class exposes and
implements the
Microsoft.ServiceBus.RelayedOnewayTransportSecurity.ProtectionLevel
setting on the Microsoft.ServiceBus.NetEventRelayBinding and
Microsoft.ServiceBus.NetOnewayRelayBinding bindings. In contrast, the
Microsoft.ServiceBus.HttpRelayTransportSecurity type sets proxy credentials
for Microsoft.ServiceBus.BasicHttpRelayBinding and
Microsoft.ServiceBus.WS2007HttpRelayBinding bindings. As with the previous
properties, Transport security generally follows the WCF security model.
RelayClientAuthenticationType
Controls whether clients of a service are required to present a security token issued by
Access Control to the Service Bus when it sends messages. Therefore, this security
property is unique to the Service Bus, and is the focus of topics in this section of the
documentation. Services are always required to authenticate with Access Control and
present an authorization token to the Service Bus; otherwise they cannot register
endpoints or create message buffers, each of which engages Service Bus resources.
However, clients are required to authenticate with the Service Bus only if the
Microsoft.ServiceBus.RelayClientAuthenticationType is set to
Microsoft.ServiceBus.RelayClientAuthenticationType.RelayAccessToken.
Setting Microsoft.ServiceBus.RelayClientAuthenticationType to
Microsoft.ServiceBus.RelayClientAuthenticationType.None waives the
requirement of a token. If you are providing your own authentication or if you do not
need authentication, you may want to opt out of authentication on the client (sender) in
the Service Bus leg of the communication. The default value is
Microsoft.ServiceBus.RelayClientAuthenticationType.RelayAccessToken.
In addition, every binding contains the Scheme property, which defines the scheme used to
encode information. For HTTP-based bindings (such as
Microsoft.ServiceBus.BasicHttpRelayBinding, the default scheme is HTTPS, which includes
its own security protocols.
This section describes specific processes for using authentication on the Service Bus.
In This Section
How to: Set Security and Authentication on a Service Bus Application
Setting Security on a REST-based Service Bus Application
180
Choosing Authentication for a Service Bus Application
Choosing a Type of Relay Authentication
How to: Modify the Service Bus Connectivity Settings
Creating a Service Bus URI
181
</behavior>
</endpointBehaviors>
</behaviors>
In this procedure, the issuer name and secret are held directly in the App.config file. It is
recommended that you implement some form of security on any configuration file that
contains such security information.
Once you have defined the credentials in the App.config file, the application will use the
security configuration automatically. There are no additional steps necessary.
182
to the endpoint and access the Service Bus.
183
As with other applications, you can configure the authentication in an App.config file or
programmatically.
2. Set the RelayClientAuthenticationType field to None.
<bindings>
<!-- Application Binding -->
<webHttpRelayBinding>
<binding name="default">
<security relayClientAuthenticationType="None" />
</binding>
</webHttpRelayBinding>
</bindings>
This allows the service to authenticate with the Service Bus (as required), but also
enables any client to connect, without authentication required. In this scenario, the
App.config file defines the type of security to use for the whole scenario, but the
programmatic configuration (in step 1) overrides the App.config file – which is necessary,
because it is impossible to have “None” for service authentication.
If you use the RelayAccessToken option for the
Microsoft.ServiceBus.Configuration.TcpRelayTransportElement.RelayClientAuthentication
Type property, the Service Bus provides a security layer over plain HTTP services that require
authentication and authorization to be performed before any HTTP traffic is forwarded to the
listening service. If Relay authentication is enabled on the Service Bus, the required security
token can be provided through programmatic credentials.
If you decide to implement programmatic credentials, you can use any of the authentication
options available to Service Bus through the Access Control service, such as shared secret or
simple Web tokens. For more information, seeHow to: Set Security and Authentication on a
Service Bus Application. The following procedure shows a simplified procedure for creating a
Web token.
184
behavior.CredentialType =
TransportClientCredentialType.SimpleWebToken;
T:Microsoft.ServiceBus.TransportClie Description
ntEndpointBehavior members
Microsoft.ServiceBus.Configuratio The
n.TransportClientEndpointBehavio Microsoft.ServiceBus.Configuration.TransportClientE
rElement.CredentialType ndpointBehaviorElement.CredentialType property
specifies which authentication method will be used on the
endpoint. The possible values for this property are as
follows:
•
Microsoft.ServiceBus.TransportClientCredenti
alType.Saml: this option specifies that the client
credential is provided in the Security Assertion
Markup Language (SAML) format, over the Secure
Sockets Layer protocol. This option requires that you
write your own SSL credential server.
•
Microsoft.ServiceBus.TransportClientCredenti
alType.SharedSecret: This option specifies that the
client credential is provided as a self-issued shared
secret that is registered with Access Control through
185
T:Microsoft.ServiceBus.TransportClie Description
ntEndpointBehavior members
the Windows Azure portal. This option requires no
additional settings on the
Microsoft.ServiceBus.TransportClientEndpointBe
havior.Credentials property.
•
Microsoft.ServiceBus.TransportClientCredenti
alType.SimpleWebToken: This option specifies that
the client credential is provided as a self-issued
shared secret that is registered with Access Control
through the Windows Azure portal, and presented in
the emerging industry-standard format called simple
Web token (SWT). Similar to the shared secret
option, this option requires no additional settings on
the
Microsoft.ServiceBus.TransportClientEndpointBe
havior.Credentials property.
•
Microsoft.ServiceBus.TransportClientCredenti
alType.Unauthenticated: This option specifies that
there is no client credential provided. This option
avoids acquiring and sending a token. It is used by
clients that are not required to authenticate, based on
the policy of their service binding. Note that this
setting might leave data nonsecure if not used
together with another security measure.
T:Microsoft.ServiceBus.RelayClientAuthenticationType Description
value
186
T:Microsoft.ServiceBus.RelayClientAuthenticationType Description
value
henticationType.RelayAccessToken access token to access the service
endpoint, and access control is
performed by the Windows Azure
Access Control service. If this option is
set on the service binding, all clients
must acquire and present tokens to the
Service Bus when establishing the
channel. Furthermore, all subsequent
access control is delegated to Access
Control. The relay access token may be
a shared secret, simple Web access
token, or a SAML token. This is the
default value.
Example
Description
The following example, taken from the Echo sample in the Windows Azure SDK, describes how
to set the connectivity mode in a command-line application.
188
Code
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
Note
The Service Bus performs case-insensitive comparisons of service namespaces to align
with the behavior of iis60. Because Access Control is designed as a general purpose
access control service, it performs case-sensitive comparisons of service namespaces
and scopes. Thus, applications that rely on Access Control can decide to be case
sensitive or case insensitive, depending on the needs of that application. When designing
applications that support multitenancy, you should realize that Access Control performs
case-sensitive comparisons and Service Bus performs case-insensitive comparisons, if
this difference in behavior produces unexpected results in your application. Because
Access Control prevents creating scopes that differ only by case, this difference in
behavior should not present a security issue.
189
To create an Access Control or Service Bus URI
1. Create the URI with a call to
Microsoft.ServiceBus.ServiceBusEnvironment.CreateServiceUri(System.String,Sys
tem.String,System.String) or
Microsoft.ServiceBus.ServiceBusEnvironment.CreateAccessControlUri(System.Str
ing), respectively.
Uri address = ServiceBusEnvironment.CreateServiceUri("sb",
solutionName, "EchoService");
Example
Description
The following example, taken from the Echo sample in the Windows Azure SDK, shows how to
programmatically create an Service Bus URI.
Code
Console.Write("Your Service Namespace (ex.
sb://<ServiceNamespace>.servicebus.windows.net/): ");
190
Note that, before you actually write the code that instantiates and runs a service, you must
perform several steps. The following procedure describes the setup work necessary before
hosting an Service Bus service.
In This Section
The following topics describe the most common hosting scenarios and contain information to help
with common issues related to hosting.
How to: Host a WCF Service that Uses the Service Bus Service
This topic describes how to create a WCF service host using the Windows Azure SDK.
How to: Host a Service on Windows Azure that Accesses the Service Bus
This topic describes how to create a WCF service host using the Windows Azure SDK,
that you can run in Windows Azure.
How to: Create a REST-based Service that Accesses the Service Bus
This topic describes how to use the WCF Web Programming Model to create and host a
WCF REST-style Web service that registers a REST service endpoint with the Service
Bus.
How to: Use a Third Party Hosting Service with the Service Bus
This topic describes how to create and host with a third-party hosting system a WCF
Web service that registers a service endpoint with the Service Bus.
191
Hosting Behind a Firewall with the Service Bus
This topic describes some of the important items to remember when hosting behind a
firewall.
See Also
How to: Expose a Metadata Endpoint
How to: Host a WCF Service that Uses the Service Bus Service
Hosting the service is the final step in creating a Windows Azure Service Bus application. Before
reaching this point, you will have defined and implemented the service contract, defined and
configured the service endpoint, and created the security credentials. For more information about
what you must do before hosting the application, see Building a Service for the Service Bus. The
next step is to put all these separate parts together and get them running. This process is
accomplished through the service host, which takes the URL of your project, together with the
contract, and creates a connection to the Service Bus.
The first procedure describes how to create a service that uses the Service Bus with the
configuration settings defined programmatically. The second procedure shows how to create a
service when most of the configuration is specified in the App.config file. This procedure follows
the NetOneWay sample in the Windows Azure SDK. For a hybrid approach that uses both
programmatic configuration and also an App.config file, see steps 1 through 4 of the Service Bus
Relayed Messaging Tutorial.
For a complete discussion of hosting an application, see Hosting Services in the Windows
Communication Foundation (WCF) documentation.
193
1. Create the name of the project to expose on the Service Bus:
string serviceBusProjectName = "myProjectNameHere";
Example
Description
The following example shows how to programmatically define and create a service application.
Code
class Program
194
string issuerSecret = "IssuerSecret";
sharedSecretServiceBusCredential.CredentialType =
TransportClientCredentialType.SharedSecret;
sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName =
issuerName;
sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret =
issuerSecret;
ContractDescription contractDescription =
ContractDescription.GetContract(typeof(IEchoContract), typeof(EchoService));
serviceEndPoint.Behaviors.Add(sharedSecretServiceBusCredential);
host.Description.Endpoints.Add(serviceEndPoint);
host.Open();
Console.ReadLine();
host.Close();
195
//Service that is configured mainly with an App.config file
class Program
host.Open();
Console.ReadLine();
host.Close();
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>
196
<sharedSecret issuerName="ISSUER_NAME" issuerSecret="ISSUER_SECRET" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netOnewayRelayBinding>
</netOnewayRelayBinding>
</bindings>
<services>
<service name="Microsoft.ServiceBus.Samples.OnewayService">
binding="netOnewayRelayBinding" bindingConfiguration="default"
</service>
</services>
</system.serviceModel>
</configuration>
See Also
Hosting a WCF Service in IIS
197
Windows Azure is not integrated with Windows Azure. Therefore,, Windows Azure does not
install the Service Bus Bus assembly. Due to Windows Azure security restrictions, you cannot
install the Windows Azure SDK on the Windows Azure platform. Therefore, to run a Service
Bus application on Windows Azure, you must redistribute the Service Bus assembly with your
Service Bus application. For more information about packaging an assembly with your
application, see the following procedure.
• Windows Azure does not store Service Bus and Access Control configuration
information in the Machine.config file
Because Windows Azure does not install the Windows Azure SDK, the Machine.config file on
a Windows Azure computer has no information about Service Bus bindings or endpoints. As
stated previously, Windows Azure security restrictions prevent you from modifying the
Windows Azure Machine.config file. Therefore, there are two options to make Service Bus
and Access Control configuration information available to your Service Bus applications.
a. The recommended solution is to use the Service Bus APIs to programmatically configure
your application. For example, although you could store name and password information
in the App.config file, you would programmatically set any relay binding configurations.
For more information about setting configuration programmatically, see Configuring a
WCF Service to Register with the Service Bus.
b. The second solution is to manually modify the App.config file for your application by
adding all of the relevant information. Once you do this, you can use the App.config file to
configure bindings and endpoints. To do so, you can see the Machine.config file on a
computer that has the Windows Azure SDK installed, find all Windows Azure-related
configuration information, and copy them to your application App.config file. While this
lets you use the App.config file on the host service, it will be difficult to test your code: you
may encounter duplication issues with the Machine.config file of the local test computer,
which will already have the Windows Azure SDK installed. Therefore, we recommend
that you use the previous option, and set everything programmatically.
• The Service Bus Service Bus must have Full Trust authorization to run on Windows
Azure
As with all other Service Bus applications, you must make sure that the operating system is
running with Full Trust authorization. This can be set in the ServiceDefinition.csdef file of your
Windows Azure project, using the following procedure.
198
To set the Windows Azure application to Full Trust
1. In the ServiceDefinition.csdef file in your project, set the enableNativeCodeExecution field
to "true", as shown in the following code. Replace "ApplicationNameHere" with the name
of your application:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="ApplicationNameHere"
xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/Se
rviceDefinition">
<WebRole name="WebRole" enableNativeCodeExecution="true">
<InputEndpoints>
<!-- Must use port 80 for http and port 443 for https when
running in the cloud -->
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</InputEndpoints>
</WebRole>
<WorkerRole name="WorkerRole" enableNativeCodeExecution="true">
</WorkerRole>
</ServiceDefinition>
199
REST-based service application, see the Service Bus Message Buffer Tutorial, which is in
turn based on the WebHttp sample in the Windows Azure SDK.
• Message Buffer applications
The Message Buffer is an Service Bus feature that exposes a REST interface to a buffer
location. Sender applications can use this message buffer to temporarily store messages and
events, similar to any other buffer. Similarly, client applications can subscribe to the message
buffer to receive stored messages or events. Because the interface is exposed through the
Service Bus, it is available to any application that can connect to the Internet. Because the
message buffer is a REST-style interface, you can connect to it using non-WCF style
applications, such as JavaScript applications, Web browsers, and other non-Microsoft
products. This includes writing services in JavaScript. However, because this technology is
so different from a typical Service Bus application, it has its own section of the
documentation. For more information about creating applications that interact with the
message buffer, see Service Bus Message Buffer Overview.
Because message buffers have a dedicated section in the documentation, this topic focuses
mainly on the details of creating a basic Service Bus application that uses the REST standard.
The process of hosting a REST-based Service Bus application is very similar to hosting a
standard Service Bus application. The main differences are in the contract and configuration: the
actual hosting process is basically the same.
To host a Service Bus service application that complies with the REST standard
1. Create the service by using the standard pattern as defined in Building a Service for the
Service Bus; that is, define and implement a service contract, configure and implement
the service host, and so on.
a. When applying the System.ServiceModel.OperationContractAttribute attribute to
the service contract, make sure that you apply the relevant attributes to identify the
REST-based members. For more information, see How to: How to: Expose a REST-
based Web Service Through the Service Bus.
The following example code shows how to tag an interface member as a REST-style
GET member.
public interface IImageContract
{
[OperationContract, WebGet]
Stream GetImage();
}
b. When implementing the contract, set the appropriate content type header for the
outgoing Web responses, as defined by the needs of your application.
public ImageService()
{
this.bitmap = Image.FromFile(imageFileName);
200
}
stream.Position = 0;
WebOperationContext.Current.OutgoingResponse.ContentType =
"image/jpeg";
return stream;
}
201
behaviorConfiguration="default">
<endpoint name="RelayEndpoint"
contract="Microsoft.ServiceBus.Samples.IImageContract"
binding="webHttpRelayBinding"
bindingConfiguration="default"
behaviorConfiguration="sharedSecretClientCredentials"
address="" />
</service>
Here, the ABC is linked to the endpoint in the App.config file. For more information about
configuring an application, see Configuring a WCF Service to Register with the Service
Bus.
The only binding to use for a service endpoint in a REST-based Service Bus application
is Microsoft.ServiceBus.WebHttpRelayBinding.
5. If necessary, disable client authentication.
<bindings>
<!-- Application Binding -->
<webHttpRelayBinding>
<binding name="default">
<security relayClientAuthenticationType="None" />
</binding>
</webHttpRelayBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
202
<transportClientEndpointBehavior
credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="ISSUER_NAME"
issuerSecret="ISSUER_SECRET" />
</clientCredentials>
</transportClientEndpointBehavior>
</behaviors>
In this example, the security is defined in the App.config file. For more information about
security, see Securing and Authenticating a Service Bus Connection.
7. Open the Service with a call to WebServiceHost.Open:
host.Open()
8. When you are finished, close the host with WebServiceHost.Close.
host.Close();
How to: Use a Third Party Hosting Service with the Service Bus
It is possible to run an application that uses the Windows Azure Service Bus on a third-party
hosting platform. There are no special settings that you must use in order to deploy your
application on the hosting service, other than what the hosting service requires. There are also no
special security requirements for accessing the Service Bus from a third-party system. However,
in order to get your application to run correctly, there are two things to note, which are very similar
to running an application on Windows Azure:
• The hosting service may not install the Windows Azure SDK
If the hosting service does not have the Windows Azure SDK installed, you cannot know for
sure that the Microsoft.ServiceBus.dll assembly is available for your application to use.
Therefore, you must make sure that the appropriate assembly is packaged and redistributed
with your application. To do so, see the following procedure.
• The hosting service may not have the appropriate listings in the Machine.config file
Because the third-party hosting service may not have the Windows Azure SDK installed, the
Machine.config file on the host has no information about Service Bus bindings or endpoints.
Due to security restrictions on many hosting services, you will likely not be able to install the
SDK on the host computer in order to add those configuration elements to the Machine.config
file. Therefore, the App.config file for your Service Bus application will likely not have any
information specific to Windows Azure in it.
There are two solutions to this issue.
203
a. The recommended solution is to use the Windows Azure APIs to programmatically
configure your application. For example, although you could store name and password
information in the App.config file, you would programmatically set any relay binding
configurations. For more information about setting the configuration programmatically,
see Configuring a WCF Service to Register with the Service Bus.
b. The second solution is to manually modify the App.config file for your application by
adding all of the relevant Service Bus information. Once you do this, you can use the
App.config file to configure bindings and endpoints. To do so, you can see the
Machine.config file on a computer that has the Windows Azure SDK installed, find all
Windows Azure related configuration information, and copy it to the App.config file for
your application. Although this will let you use the App.config file on the host service, it
will be difficult to test your code: you may experience duplication issues with the
Machine.config file on the local test computer, which will already have the Windows
Azure SDK installed. Therefore, we recommend that you use the previous option, and set
everything programmatically.
204
firewall. Therefore, you might have to explicitly configure the WinHTTP proxy settings with the
appropriate credentials.
Set OpenTimeout
Setting the connectivity mode to HTTP (that is, ConnectivityMode = http) may cause connections
in the presence of some proxies to be very slow. For example, some connections can require up
to 20 seconds to connect. Extending the OpenTimeout option for the service to up to two
minutes can help, because you might run out of time between the acquisition of the Access
Control token and getting the Web stream working. After the Web stream is established, the
throughput often improves.
In This Section
How to: Create a WCF SOAP Client Application for the Service Bus
This topic describes how to create a SOAP-based client application that uses Windows
Communication Foundation (WCF).
See Also
Building a Service Bus Client Application
How to: Create a WCF SOAP Client Application for the Service
Bus
The following topic describes how to create a traditional client application that accesses the
Windows Azure Service Bus. For a complete discussion of building a client application, see
Building Clients in the Windows Communication Foundation (WCF) documentation. The
205
following procedure is a simplified process for creating a client application that highlights the
features unique to the Service Bus. For a complete sample, see the Echo sample in the Windows
Azure SDK, or Step 5: Create a WCF Client for the Service Contract in the Service Bus Relayed
Messaging Tutorial.
You can retrieve the contract from the service in a variety of ways, such as through
metadata exposed by the service. For more information, seeHow to: Design a WCF
Service Contract for use with the Service Bus.
2. Add references to the System.ServiceModel and Microsoft.ServiceBus namespaces
to your project:
using System.ServiceModel;
using Microsoft.ServiceBus;
206
string issuerName = Console.ReadLine();
Console.Write("Your Issuer Secret: ");
string issuerSecret = Console.ReadLine();
}
Note
The previous code example assumes that the service endpoint requires issuer
name and secret credentials. Service endpoints may not require authentication; if
one did not require authentication, setting the issuer name and secret would also
not be necessary.
The type of security and authentication that is required to connect is defined by the
service. You can retrieve this information in a variety of ways, such as through metadata
that the service exposes. For more information, seeHow to: Design a WCF Service
Contract for use with the Service Bus. This topic assumes that the Service Bus endpoint
requires client applications to authenticate and uses issuer name and secret credentials.
(An endpoint may not require any authentication, although this example does.) You can
also use other credential types, such as a simple Web token (SWT), or SAML. At this
point, you can also set the client transport or message-level security. However, for many
scenarios, the default settings are sufficient. For more information, seeSecuring and
Authenticating a Service Bus Connection.
4. Define the security credentials to use with the endpoint:
TransportClientEndpointBehavior
sharedSecretServiceBusCredential = new
TransportClientEndpointBehavior();
sharedSecretServiceBusCredential.CredentialType =
TransportClientCredentialType.SharedSecret;
sharedSecretServiceBusCredential.Credentials.SharedSecret.Iss
uerName = issuerName;
sharedSecretServiceBusCredential.Credentials.SharedSecret.Iss
uerSecret = issuerSecret;}
Note
The previous code example assumes that the service endpoint requires issuer
name and secret credentials. Service endpoints may not require authentication; if
authentication is not required, skip this step and step 8, later in this section.
5. Create a URI object pointing to the Service Bus service, as shown in the following code:
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb",
serviceNamespace, "EchoService");
In this code sample, the
207
Microsoft.ServiceBus.ServiceBusEnvironment.CreateServiceUri(System.String,Sys
tem.String,System.String) method takes the schema (“sb” for the Service Bus, used for
TCP relay connections), the service namespace, and the name of the endpoint to which
to connect. For more information, seeCreating a Service Bus URI.
6. Configure the client endpoint used to connect to the service.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<!-- Application Endpoint -->
<endpoint name="RelayEndpoint"
contract="Microsoft.ServiceBus.Samples.IEchoContract"
binding="netTcpRelayBinding"/>
</client>
</system.serviceModel>
</configuration>
In this example, the client endpoint is defined using the name “RelayEndpoint”, which is
used later to help create the channel factory. The endpoint configuration also declares
the contract defined in the first step of this procedure, as well as the fact that the binding
used to connect is a Microsoft.ServiceBus.NetTcpRelayBinding. For this procedure,
the information is declared in an App.config file. You can also define this information
programmatically. For more information, seeConfiguring a WCF Service to Register with
the Service Bus.
7. Instantiate a channel factory:
ChannelFactory<IEchoChannel> channelFactory = new
ChannelFactory<IEchoChannel>("RelayEndpoint", new
EndpointAddress(serviceUri));
This channel factory uses the type of channel defined in the client contract at the
beginning of this procedure.
8. Apply the credentials and any other behaviors to the endpoint:
channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusC
redential);
Note
The preceding code example assumes that the service endpoint requires issuer
name and secret credentials. Service endpoints may or may not require
208
authentication; if an endpoint does not require authentication, adding the
credential behavior to the client endpoint would not be required.
9. Create a new channel to the service and open it:
IEchoChannel channel = channelFactory.CreateChannel();
channel.Open();
10. Perform whatever tasks are necessary to your scenario:
Console.WriteLine("Enter text to echo (or [Enter] to
exit):");
string input = Console.ReadLine();
while (input != String.Empty)
{
try
{
Console.WriteLine("Server echoed: {0}",
channel.Echo(input));
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
input = Console.ReadLine();
}
This step consists of accessing the service application through the exposed endpoint. For
more information, seeBuilding a Service for the Service Bus.
11. When you are finished, close the channel, as shown in the following code:
channel.Close();
channelFactory.Close();
209
capabilities available to them. In this case, the only issue is what type of security and
authentication the service requires. However, in this kind of scenario, it is common for the service
to require little or no authentication. For more information, seeHow to: Create a REST-based
Service that Accesses the Service Bus. For a full example of this scenario, see the WebHttp
sample in the Windows Azure SDK, or the Service Bus Message Buffer Tutorial.
If the client has access to the Windows Azure SDK, it follows the same procedure as a standard
Service Bus client application. For more information, seeHow to: Create a WCF SOAP Client
Application for the Service Bus. The only unique feature in this scenario is that attributes such as
[WebGet] are applied to the contract you retrieve from the service. These attributes map the
contract to the REST standard. Because it is an Internet-based protocol, you will be required to
use an HTTP-based binding, such as Microsoft.ServiceBus.WebHttpRelayBinding.
In This Section
How to: Publish a Service to the Service Bus Registry
This topic describes how to use the
Microsoft.ServiceBus.ServiceRegistrySettings behavior to publish a service
endpoint in the ATOM 1.0 feed and to control the name that appears there.
210
How to: Discover and Expose a Service Bus Application
This topic describes how to navigate the endpoints published in the registry to obtain
the one to which you want to connect.
T:Microsoft.ServiceBus.ServiceRegistrySettings Description
properties
211
To add an Application to the Service Bus registry
1. Create an instance of the Microsoft.ServiceBus.ServiceRegistrySettings behavior,
using the Microsoft.ServiceBus.DiscoveryType.Public parameter.
ServiceRegistrySettings serviceRegistrySettings = new
ServiceRegistrySettings(DiscoveryType.Public);
serviceRegistrySettings.DisplayName = "MyService";
2. Add the description to the associated endpoint.
foreach (ServiceEndpoint subscriberEndpoint in
subscriberHost.Description.Endpoints)
{
subscriberEndpoint.Behaviors.Add(serviceRegistrySettings);
}
212
How to: Expose a Metadata Endpoint
A Windows Azure Service Bus metadata endpoint is a URI that exposes additional information
about a service or client application. For example, the Svcutil.exe tool uses the exposed
metadata from a service to build a contract so that a developer can access that service. Without
the metadata, the developer would have to gain access to the contract in some other way, such
as asking the creator for a copy of it directly via e-mail. Note that you can still implement an
interface without metadata: metadata just lets you easily obtain the contract if you do not already
have it. Also note that exposing a metadata endpoint differs from publishing your interface to the
ATOM feed: the metadata endpoint contains additional information about the contract, whereas
publishing on the ATOM feed just lists the service URI in a publicly-accessed database.
The following is a simplified procedure for exposing metadata on an application that uses the
Service Bus. For a complete discussion of metadata, see Metadata Architecture Overview in
the Windows Communication Foundation (WCF) documentation.
<endpoint name="MexEndpoint"
contract="IMetadataExchange"
binding="netTcpRelayBinding"
bindingConfiguration="default"
address="mex" />
</service>
</services>
<endpointBehaviors>
213
...
<endpointBehaviors>
<serviceBehaviors>
<behavior name="serviceMetadata">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
...
</service>
</services>
Warning
If the metadata endpoint is specified with a different end-to-end security mode
than the service endpoint, and uses a relative address while sharing the same
base address with the service endpoint, an exception of type
System.ArgumentException is thrown when you open the service host. The
following error message accompanies the exception: Incompatible channel
listener settings. To resolve this issue, perform one of the following
workarounds:
• Specify the address of the metadata endpoint as a fully-qualified address.
• If you want to use a relative address for the metadata endpoint that shares a base
address with the service endpoint, specify the same end-to-end security mode for
both the metadata and service endpoints.
• Use a relative address for the metadata endpoint with a base address that differs
from the base address of the service endpoint.
214
Working with a Service Bus Message Buffer
The following topics provide an overview of the Windows Azure Service Bus message buffer
feature. They also describe how to create, configure, and use an Service Bus message buffer.
In This Section
Service Bus Message Buffer Overview
How to: Configure a Service Bus Message Buffer
How to: Create and Connect to a Service Bus Message Buffer
How to: Send Messages to a Service Bus Message Buffer
How to: Retrieve a Message from a Service Bus Message Buffer
Important
The current Message Buffers feature, including their management protocol, will remain
supported for backwards compatibility. However, the general recommendation is that you
explicitly change client code to use the new Queue feature. For more information,
see Queues, Topics, and Subscriptions.
Message buffers are small, temporary cache locations in which messages can be held for a short
time until they are retrieved. Message buffers are especially useful in Web programming model
scenarios when Windows Azure Service Bus bindings are not available; for example, when the
message consumer is running on a computer that is not running Windows, or is implemented in
Java. Message buffers can be accessed by applications that use HTTP and do not require the
Windows Azure SDK. Hence, message buffers enable Web developers, mobile device
programmers, and others to integrate their applications together with the Service Bus by creating
message consumers that use HTTP requests to poll for messages.
Message buffers use the HTTP REST protocol to expose various operations on the message
buffer such as creating a message buffer, sending a message to the message buffer, and
retrieving a message from the message buffer. These operations are described in the
following Message Buffer Protocol section.
The following code example shows how to use the REST protocol to create a message buffer,
send and retrieve a message from the message buffer, and finally delete the message buffer.
This example uses System.Net.WebClient to send and receive HTTP requests. For a complete
working sample, see the PlainHttp sample in the Windows Azure SDK samples folder under
ServiceBus\ExploringFeatures\MessageBuffer.
// Prompt the user for the service namespace and issuer key.
215
string serviceNamespace = Console.ReadLine();
client.BaseAddress = string.Format("https://{0}-sb.accesscontrol.windows.net/",
serviceNamespace);
values.Add("wrap_name", "owner");
values.Add("wrap_password", ownerKey);
values.Add("wrap_scope", messageBufferLocation);
string policy =
"<entry xmlns=\"http://www.w3.org/2005/Atom\">" +
"<content type=\"text/xml\">" +
"<MessageBufferPolicy
xmlns=\"http://schemas.microsoft.com/netservices/2009/05/servicebus/connect\"/>" +
"</content>" +
216
"</entry>";
client.BaseAddress = string.Format("https://{0}.servicebus.windows.net/{1}/",
serviceNamespace, bufferName);
client.Headers[HttpRequestHeader.ContentType] =
"application/atom+xml;type=entry;charset=utf-8";
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
client.Headers[HttpRequestHeader.ContentType] = "text/xml";
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
Console.WriteLine("Message sent.");
// Retrieve message.
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
You can also use message buffers through the APIs provided by the Windows Azure SDK. This
requires the Windows Azure SDK to be installed. For more information about using message
buffers with the Windows Azure SDK, see the Using the Message Buffer with the Windows Azure
SDK section later in this topic.
217
Message Buffer Protocol
The message buffer protocol is an HTTP REST protocol that is designed to follow REST
principles and to be simple and easy to understand. The goal is to make sure that developers can
easily use the protocol from any client without requiring a library or SDK.
The protocol relies on the Access Control service HTTP authorization model to help it enforce
access control on the message buffer. This means that it uses the Simple Web Token (SWT)
mechanism that you can use to retrieve a token using HTTP, and then embed it in an HTTP
request as a header. This token includes claims that are used to determine whether an operation
should be allowed.
The protocol expects each message buffer to be located at a unique URI in the Service Bus
namespace. This URI then becomes the root for a set of resources that represents the message
buffer instance. Each resource type has a unique URI and an associated set of HTTP verbs for
interacting with it. The URIs are organized in a way that helps communicate the logical
relationships between the different types of resources.
The verbs used to interact with message buffers are modeled on standard HTTP commands. The
following is a list of these verbs:
• POST/PUT: Use to create new resources. POST is used to create a new instance of the
message resource. PUT is used to either create or update a message buffer resource. When
using POST, the address of the new resource is returned in the response.
• PUT: Use to update an existing resource.
• DELETE: Use to delete an existing resource.
• GET: Use to retrieve a representation of a resource. In this case the GET is expected to
represent a snapshot of the resource and it can be cached when appropriate.
The following is a summary of the different message buffer resources and the associated verbs
for each resource.
URI Resource
Operations
218
URI Resource
Operations
essages/head (Returns message content,
message URI, lock duration,
lock URI, and lock ID.)
For example:
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="text/xml">
<MessageBufferPolicy
xmlns="http://schemas.microsoft.com/netservices/2009/05/servicebus/connect">
<Authorization>[AuthorizationPolicy enum value]</Authorization>
<Discoverability>[DiscoverabilityPolicy enum value]</Discoverability>
<TransportProtection>[TransportProtectionPolicy enum
value]</TransportProtection>
<ExpiresAfter>PTnHnMnS</ExpiresAfter>
219
<MaxMessageCount>nnn</MaxMessageCount>
<OverflowPolicy>[OverflowPolicy enum value]</OverflowPolicy>
</MessageBufferPolicy>
</content>
</entry>
Notes:
The ExpiresAfter time interval is broken up into hours (H), minutes (M), and
seconds (S). Replace n by the corresponding amount of time for each unit of
time.
The enumeration values for the policy properties are part of the
Microsoft.ServiceBus namespace.
Response {policy-xml}
Body
The message buffer policy is returned because some policy property might be
defaulted if their value supplied in the request is invalid.
Expected HTTP Status 200 OK: The message buffer policy was successfully retrieved.
Code
220
Request Body Empty.
Expected HTTP Status 200 OK: The message buffer was successfully deleted.
Code
Resourc https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/head?ti
e URI meout={timeout-in-seconds}
The timeout parameter specifies the maximum amount of time that the retrieve
request will wait if a message is not readily available in the message buffer. The
maximum time that can be specified is 2 minutes.
HTTP DELETE
Verb
Request Empty.
Body
Respon {message-payload}
221
se Body
Resourc https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/head?ti
e URI meout={timeout-in-seconds}&lockduration={lockduration-in-secs}
The timeout parameter specifies the maximum amount of time that this request will
wait if a message is not readily available in the message buffer. The maximum time
that can be specified is 2 minutes.
The lockduration parameter specifies the time in seconds that the returned message is
locked so that no other consumer can see the message. The maximum lock duration
is 5 minutes and the minimum lock duration is 10 seconds.
HTTP POST
Verb
Request Empty.
Body
Respon X-MS-MESSAGE-LOCATION:
se https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{messa
Headers ge-id}
This header indicates the location of the message. This URI is needed to unlock or
delete the message. For more information, see the “Unlock a locked message” and
“Delete a locked message from the message buffer” tables.
X-MS-LOCK-ID: {lock-id}
This header provides the lock ID of the message. This lock ID is needed to delete the
locked message. For more information, see the “Delete a locked message from the
message buffer” table.
X-MS-LOCK-LOCATION:
https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{messa
ge-id}/{lock-id}
This header indicates the lock location for the message. This URI is needed to unlock
the message. For more information, see the “Unlock a locked message” table.
222
Respon {message-payload}
se Body
Expecte 200 OK: The message was successfully read and locked.
d HTTP 204 No Content: No messages are present in the message buffer.
Status 400 Bad Request: This request exceeds the quota of pending receivers to the buffer.
Code Please retry after some time.
410 Gone: The message buffer is no longer available.
Unlock a locked message (that is, delete a lock on a message) in the message buffer
Resource https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{mess
URI age-id}/{lock-id}
HTTP DELETE
Verb
Request Empty.
Body
Respons Empty.
e Body
Resource https://{serviceNamespace}.servicebus.windows.net/{path}/{buffer}/messages/{mess
URI age-id}?lockid={lock-id}
The lockid parameter should be a valid lock ID from the response header value “X-
MS-LOCK-ID” that is returned in the response of a non-destructive read operation.
For more information, see the “Lock a message in the message buffer” table.
HTTP DELETE
Verb
223
Request Empty.
fBody
Respons Empty.
e Body
224
The following code example shows how to configure and create a message buffer, and send and
retrieve messages from the message buffer.
string serviceNamespace = "...";
// Configure credentials.
behavior.CredentialType = TransportClientCredentialType.SharedSecret;
behavior.Credentials.SharedSecret.IssuerName = "...";
behavior.Credentials.SharedSecret.IssuerSecret = "...";
ExpiresAfter = TimeSpan.FromMinutes(2.0d),
MaxMessageCount = 100
};
// Send 10 messages.
Message message;
string content;
225
// Retrieve a message (destructive read).
message = client.Retrieve();
content = message.GetBody<string>();
message.Close();
message = client.PeekLock();
content = message.GetBody<string>();
client.DeleteLockedMessage(message);
message.Close();
Important
Because message buffer contents are stored in active memory, there are no strong fault
tolerance or reliability guarantees. If the server hosting a message buffer crashes, you
may lose messages. In the event of a server crash, you do not necessarily lose the buffer
itself: knowledge of the buffer, including policy settings, is distributed across multiple
servers and can be recovered. However, any messages in your buffer at the time of the
crash are lost. Therefore, if you are designing an application that requires a high degree
of message reliability, we recommend that you provide for message redundancy and
recovery through another way.
226
MessageBufferPolicy Properties Description
227
Microsoft.ServiceBus.TransportProtectionP
olicy.AllPaths, which means that messages
must be sent and received from the message
buffer using a secure communication channel.
You apply a policy to the message buffer when you create the message buffer.
A message buffer can be thought of as a service hosted on a Windows Azure Service Bus
endpoint. Similar to other services hosted on Service Bus endpoints, you must create a message
buffer with credentials that enable manage-level operations upon the target service namespace.
Therefore, to create and configure an Service Bus message buffer, you must first obtain a valid
token from the Access Control service.
228
string token =
Uri.UnescapeDataString(response.Split('&').Single(value =>
value.StartsWith("wrap_access_token=",
StringComparison.OrdinalIgnoreCase)).Split('=')[1]);
To build and run the previous code, add the following using statements at the top of the
class file:
using System.Net;
using System.Collections.Specialized;
2. Create the message buffer policy XML string that will be used when you create the
message buffer. The following message buffer policy configures the message buffer with
an expiration time of 2 minutes and a maximum capacity of 20 messages.
// Create the message buffer policy.
string policy =
"<entry xmlns=\"http://www.w3.org/2005/Atom\">" +
"<content type=\"text/xml\">" +
"<MessageBufferPolicy
xmlns=\"http://schemas.microsoft.com/netservices/2009/05/serv
icebus/connect\">" +
"<ExpiresAfter>PT0H2M0S</ExpiresAfter>" +
"<MaxMessageCount>20</MaxMessageCount>" +
"</MessageBufferPolicy>" +
"</content>" +
"</entry>";
3. After you have finished creating your message buffer policy, you can apply the
configuration information at the time that you create the message buffer and start to send
and receive messages. For more information, seeHow to: Create and Connect to a
Service Bus Message Buffer.
How to configure a Service Bus message buffer using the Windows Azure SDK
229
1. Configure your credentials as you would any other application that uses the Service Bus.
TransportClientEndpointBehavior behavior = new
TransportClientEndpointBehavior();
behavior.CredentialType =
TransportClientCredentialType.SharedSecret;
behavior.Credentials.SharedSecret.IssuerName = "...";
behavior.Credentials.SharedSecret.IssuerSecret = "...";
To build and run the previous code, you must add a reference to the
Microsoft.ServiceBus.dll assembly. Also, add the following using statement at the top of
the class file to reference this namespace, as follows:
using Microsoft.ServiceBus;
2. Configure the message buffer policy using the
Microsoft.ServiceBus.MessageBufferPolicy class. The following message buffer
policy configures the message buffer with a maximum capacity of 20 messages and an
expiration time of 2 minutes.
MessageBufferPolicy policy = new MessageBufferPolicy();
policy.MaxMessageCount = 20;
policy.ExpiresAfter = TimeSpan.FromMinutes(2);
3. After you have finished configuring your message buffer policy, you can apply the
configuration at the time that you instantiate the message buffer and start to send and
receive messages. For more information, see How to: Create and Connect to a Service
Bus Message Buffer. You can also use the
Microsoft.ServiceBus.MessageBufferClient.GetPolicy method to retrieve the
message buffer policy at any time in order to discover the current configuration settings.
230
windows.net/{path}/{buffer} Service Bus with the specified policy.
The following table lists the methods available to create, access, and delete a message buffer
using the Windows Azure SDK.
Method Description
Microsoft.ServiceBus.Mes Creates a message buffer on the Service Bus with the specified
sageBufferClient.CreateM policy and location.
essageBuffer(Microsoft.S
erviceBus.TransportClient
EndpointBehavior,System
.Uri,Microsoft.ServiceBus.
MessageBufferPolicy)
Note
You can create only one message buffer at a given Service Bus endpoint. Furthermore,
when a message buffer is open on a given endpoint, no other services can be open on
that same endpoint.
To create and delete a Service Bus message buffer using the REST protocol
1. Send a PUT HTTP request to create a message buffer using the authorization header
and message buffer policy previously created in How to: Configure a Service Bus
Message Buffer.
WebClient client = new WebClient();
client.BaseAddress =
string.Format("https://{0}.servicebus.windows.net/{1}/",
231
serviceNamespace, bufferName);
client.Headers[HttpRequestHeader.ContentType] =
"application/atom+xml;type=entry;charset=utf-8";
client.Headers[HttpRequestHeader.Authorization] =
authHeaderValue;
client.UploadData(String.Empty, "PUT",
Encoding.UTF8.GetBytes(policy));
2. At this point, you can send and receive messages from the message buffer. For more
information, see How to: Send Messages to a Service Bus Message Buffer and How to:
Retrieve a Message from a Service Bus Message Buffer.
3. To maintain the existence of the message buffer, periodically request a message from
the buffer.
A message buffer renews its own lifespan implicitly whenever a request for a message is
received. This is the only method currently supported for renewing the lifespan of a
message buffer.
4. When finished, you can delete the message buffer by sending the following DELETE
HTTP request.
client.Headers[HttpRequestHeader.Authorization] =
authHeaderValue;
client.UploadData(String.Empty, "DELETE", new byte[0]);
You do not have to delete the message buffer when you are finished: all message buffers
have an expiration time that causes the Service Bus to automatically delete the buffer.
However, you may want to delete the buffer before this expiration time. For more
information, see the Microsoft.ServiceBus.MessageBufferPolicy.ExpiresAfter
property.
To create and delete a Service Bus message buffer using the Windows Azure SDK
1. Create a URI that contains the address of the buffer.
Uri bufferLocation = new Uri("https://" + serviceNamespace +
".servicebus.windows.net/services/MyBuffer");
2. Create the buffer by calling the
Microsoft.ServiceBus.MessageBufferClient.CreateMessageBuffer(Microsoft.Servic
eBus.TransportClientEndpointBehavior,System.Uri,Microsoft.ServiceBus.Message
BufferPolicy) method.
MessageBufferClient client =
MessageBufferClient.CreateMessageBuffer(behavior,
bufferLocation, policy);
232
You can also obtain access to a pre-existing message buffer by calling the
Microsoft.ServiceBus.MessageBufferClient.GetMessageBuffer(Microsoft.ServiceBu
s.TransportClientEndpointBehavior,System.Uri) method.
3. At this point, you can send and receive messages from the message buffer. For more
information, see How to: Send Messages to a Service Bus Message Buffer and How to:
Retrieve a Message from a Service Bus Message Buffer.
4. To maintain the existence of the message buffer, periodically request a message from
the buffer.
A message buffer renews its own lifespan implicitly whenever a request for a message is
received. This is the only method currently supported for renewing the lifespan of a
message buffer.
5. When finished, you can close the message buffer by calling the
Microsoft.ServiceBus.MessageBufferClient.DeleteMessageBuffer method.
You do not have to delete the message buffer when you are finished: all buffers have an
expiration time that causes the Service Bus to automatically delete the buffer. However,
you may want to delete the buffer before this expiration time. For more information, see
the Microsoft.ServiceBus.MessageBufferPolicy.ExpiresAfter property.
The following is a description of the methods that you can use to send a message to a message
buffer using the API in the Windows Azure SDK.
Method Description
233
Microsoft.ServiceBus.MessageBufferClient.Se Attempts to send the specified message for a
nd(System.ServiceModel.Channels.Message,S time interval equal to the specified timeout
ystem.TimeSpan) value.
2. Alternatively, by appending a time-out parameter to the URI, you can specify the time
interval during which the attempt to send the message is made.
client.UploadData("messages?timeout=20", "POST",
Encoding.UTF8.GetBytes("<msg1>This is message #1</msg1>"));
234
The following example, taken from the code example in Service Bus Message Buffer
Overview, shows how to send several messages to a message buffer.
MessageBufferClient client =
MessageBufferClient.CreateMessageBuffer(behavior,
bufferLocation, policy, messageVersion);
// Send 10 messages.
for (int i = 0; i < 10; ++i)
{
client.Send(Message.CreateMessage(messageVersion,
messageAction, "Message #" + i));
}
To build and run the previous code, you must add references to the
Microsoft.ServiceBus.dll and System.ServiceModel.dll assemblies. Also, add the
following using statements at the top of the class file to reference these namespaces:
using Microsoft.ServiceBus;
using System.ServiceModel.Channels;
235
https://{serviceNamespace}.serviceb DELETE Retrieves the first message and deletes it
us.windows.net/{path}/{buffer}/mess from the message buffer. The optional
ages/head?timeout={timeout-in- time-out parameter specifies the length of
seconds} time for the operation to finish.
The following is a description of the methods you can use for destructive and non-destructive
retrieval of a message from a message buffer using the API in the Windows Azure SDK.
Method Description
236
the specified time-out interval for a message to
arrive.
237
LOCATION"];
return Encoding.UTF8.GetString(response);
}
2. After you have performed a peek/lock operation on the message, you can delete the
locked message from the message buffer using the message location and lock ID
returned by the peek/lock operation.
static void DeleteLockedMessage(string authHeaderValue,
string messageLocation, string lockId)
{
WebClient webClient = new WebClient();
webClient.BaseAddress = string.Format("{0}?lockid={1}",
messageLocation, lockId);
webClient.Headers[HttpRequestHeader.ContentType] =
"application/atom+xml;type=entry;charset=utf-8";
webClient.Headers[HttpRequestHeader.Authorization] =
authHeaderValue;
webClient.UploadData(string.Empty, "DELETE", new
byte[0]);
}
3. Alternatively, if you do not want to delete the message, you can release the lock on the
locked message using the lock location returned by the peek/lock operation.
static void UnlockMessage(string authHeaderValue, string
lockLocation)
{
WebClient webClient = new WebClient();
webClient.BaseAddress = lockLocation;
webClient.Headers[HttpRequestHeader.ContentType] =
"application/atom+xml;type=entry;charset=utf-8";
webClient.Headers[HttpRequestHeader.Authorization] =
authHeaderValue;
webClient.UploadData(string.Empty, "DELETE", new
byte[0]);
}
Example
Description
The following code example, taken from the code sample in Service Bus Message Buffer
Overview, describes how to perform a destructive read in addition to a peek/lock read.
Code
// Retrieve a message (destructive read)
message.Close();
239
// Retrieve a message (peek/lock)
message = client.PeekLock();
content = message.GetBody<string>();
client.DeleteLockedMessage(message);
message.Close();
<access-policy>
<cross-domain-access>
<policy>
<domain uri="https://*"/>
<domain uri="http://*"/>
</allow-from>
<grant-to>
240
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
For the Access Control service, by default all service namespaces have cross-domain access set
up. For the Service Bus, you must explicitly configure cross-domain access. To enable uploads of
the policy file to the root of the service namespace, the Service Bus provides REST commands
(PUT, DELETE) that enable this. The following example is taken from the
MessageBufferForSilverlight sample application in the Windows Azure SDK:
static HttpStatusCode PublishClientAccessPolicy(string serviceNamespace, string
authHeaderValue, byte[] fileContentArray)
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create(string.Format("https://{0}.{1}/clientaccesspolicy.xml",
serviceNamespace, ServiceBusUriPostFix));
request.Method = "PUT";
request.ContentType = "text/xml";
request.ContentLength = fileContentArray.Length;
request.Headers[AuthorizationHeader] = authHeaderValue;
dataStream.Write(fileContentArray, 0, fileContentArray.Length);
dataStream.Close();
return SendHttpRequestAndGetResponse(request);
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create(string.Format("https://{0}.{1}/clientaccesspolicy.xml",
serviceNamespace, ServiceBusUriPostFix));
241
request.Method = "DELETE";
request.Headers[AuthorizationHeader] = authHeaderValue;
return SendHttpRequestAndGetResponse(request);
webClient.BaseAddress = bufferLocation;
webClient.Headers[XMSAuthorizationHeader] = this.authHeaderValue;
webClient.Headers[HttpRequestHeader.ContentType] =
"application/atom+xml;type=entry;charset=utf-8";
webClient.UploadStringCompleted += createMessageBufferCompleted;
For more information, see the MessageBufferForSilverlight sample application in the Windows
Azure SDK.
242
Service Bus Troubleshooting
The following topics contain information and recommendations for troubleshooting applications
that use the Windows Azure Service Bus.
In This Section
Troubleshooting the Service Bus
Hosting Behind a Firewall with the Service Bus
Connectivity Issues
The following troubleshooting topics contain information about how to connect to the Service Bus.
If you cannot find your solution later in this section, you may want to consider one of the following
possibilities:
• Run a network trace – the network may be down. Using Network Monitor to determine the
status of the network may assist you in debugging your problem.
244
run, Visual Studio is not affected. After the service starts, set the client project as the
startup project, then run it.
• Ensure that you have set the Copy Local property for the Microsoft.ServiceBus.dll assembly
(in Visual Studio) to true. The cloud servers do not have the Windows Azure SDK installed.
Therefore, you must include the assembly with your package. Without it, your worker role will
not run correctly.
• Confirm that you can, in fact, connect to the Internet using HTTP port 80 and TCP port 808.
Set OpenTimeout
Setting the connectivity mode to HTTP (that is, ConnectivityMode = http) may cause connections
in the presence of some proxies to be very slow. For example, some connections can require up
to 20 seconds to connect. Extending the OpenTimeout option for the service to up to two
minutes can help, because you might run out of time between the acquisition of the Access
246
Control token and getting the Web stream working. After the Web stream is established, the
throughput often improves.
RelayConfigurationInstaller.exe Tool
The RelayConfigurationInstaller.exe tool is located in the <installdir>/Assemblies directory of the
Windows Azure SDK, and enables you to easily add the Machine.config settings necessary for
the Service Bus bindings to be supported in the configuration file. You can also use the
Microsoft.ServiceBus.Configuration.RelayConfigurationInstaller class to accomplish this
programmatically.
The primary scenario for the RelayConfigurationInstaller.exe tool is to help in installing the
necessary Machine.config or App.config information that is required to run an Service Bus
application on a computer that does not have the Service Bus installed. However, in most
scenarios, the application installer for the Service Bus application automatically installs the
necessary configuration information. Therefore, the tool or class would likely be used by
developers who want additional control over the installation process.
Command-line Options
/i
Adds the entries to the configuration file to allow an application that uses that
configuration to use Service Bus elements.
/u
Removes the entries from the Machine.config file.
247
Throughout this topic, the term “client” refers to any entity that accesses the Service Bus. A client
can take the role of a sender or a receiver. The term “sender” is used for a Service Bus queue or
topic client that sends messages to a Service Bus queue or topic. The term “receiver” refers to a
Service Bus queue or subscription client that receives messages from a Service Bus queue or
subscription.
Mechanisms
This section introduces different concepts employed by the Service Bus to help boost
performance.
Protocols
The Service Bus enables clients to send and receive messages via two protocols: the Service
Bus client protocol, and HTTP. The Service Bus client protocol is more efficient, because it
maintains the connection to the Service Bus service as long as the message factory exists. It also
implements batching and prefetching. The Service Bus client protocol is available for .NET
applications using the .NET managed API.
Unless explicitly mentioned, all content in this topic assumes the use of the Service Bus client
protocol.
Concurrent operations
Performing an operation (send, receive, delete, etc.) takes some time. This time includes the
processing of the operation by the Service Bus service in addition to the latency of the request
and the reply. To increase the number of operations per time, operations must execute
concurrently. You can do this in several different ways:
Asynchronous operations: the client pipelines operations by performing asynchronous
operations. The next request is started before the previous request is completed. The
following is an example of an asynchronous send operation:
BrokeredMessage m1 = new BrokeredMessage(body);
BrokeredMessage m2 = new BrokeredMessage(body);
248
queueClient.BeginSend(m1, processEndSend, queueClient); // Send
message 1.
queueClient.BeginSend(m2, processEndSend, queueClient); // Send
message 2.
249
obtained with a single factory varies greatly with TCP round-trip times and message size. In
benchmarks, a maximum throughput per factory of around 800msg/s (message size: 1KB)
has been observed. To obtain rates beyond this, you should use multiple messaging
factories.
Receive mode
When creating a queue or subscription client, you can specify a receive mode: Peek-lock or
Receive and delete. The default receive mode is
Microsoft.ServiceBus.Messaging.ReceiveMode.PeekLock. When operating in this mode, the
client sends a request to receive a message from the Service Bus. After the client has received
the message, it sends a request to complete the message.
When setting the receive mode to
Microsoft.ServiceBus.Messaging.ReceiveMode.ReceiveAndDelete, both steps are combined
in a single request. This reduces the overall number of operations, and can improve the overall
message throughput. This performance gain comes at the risk of losing messages.
The September 2011 release of the Service Bus does not support transactions for receive-and-
delete operations. In addition, peek-lock semantics are required for any scenarios in which the
client wants to defer or deadletter a message.
Client-side batching
Client-side batching enables a queue or topic client to delay the sending of a message for a
certain period of time. If the client sends additional messages during this time period, it transmits
the messages in a single batch. Client-side batching also causes a queue/subscription client to
batch multiple Complete requests into a single request. Batching is only available for
asynchronous Send and Complete operations. Synchronous operations are immediately sent to
the Service Bus service. Batching does not occur for peek or receive operations, nor does
batching occur across clients.
If the batch exceeds the maximum message size, the last message is removed from the batch,
and the client immediately sends the batch. The last message becomes the first message of the
next batch. By default, a client uses a batch interval of 20ms. You can change the batch interval
by setting the
Microsoft.ServiceBus.Messaging.NetMessagingTransportSettings.BatchFlushInterval
property before creating the messaging factory. This setting affects all clients that are created by
this factory.To disable batching, set the
Microsoft.ServiceBus.Messaging.NetMessagingTransportSettings.BatchFlushInterval
property to TimeSpan.Zero. For example:
MessagingFactorySettings mfs = new MessagingFactorySettings();
mfs.TokenProvider = tokenProvider;
mfs.NetMessagingTransportSettings.BatchFlushInterval = TimeSpan.FromSeconds(0.05);
250
Batching does not affect the number of billable messaging operations, and is available only for
the Service Bus client protocol. The HTTP protocol does not support batching.
qd.EnableBatchedOperations = false;
Queue q = namespaceManager.CreateQueue(qd);
Batched store access does not affect the number of billable messaging operations, and is a
property of a queue, topic, or subscription. It is independent of the receive mode and the protocol
that is used between a client and the Service Bus service.
Prefetching
Prefetching enables the queue or subscription client to load additional messages from the service
when it performs a receive operation. The client stores these messages in a local cache. The size
of the cache is determined by the
Microsoft.ServiceBus.Messaging.QueueClient.PrefetchCount and
Microsoft.ServiceBus.Messaging.SubscriptionClient.PrefetchCount properties. Each client
that enables prefetching maintains its own cache. A cache is not shared across clients. If the
client initiates a receive operation and its cache is empty, the service transmits a batch of
messages. The size of the batch equals the size of the cache or 256KB, whichever is smaller. If
the client initiates a receive operation and the cache contains a message, the message is taken
from the cache.
When a message is prefetched, the service locks the prefetched message. By doing this, the
prefetched message cannot be received by a different receiver. If the receiver cannot complete
the message before the lock expires, the message becomes available to other receivers. The
prefetched copy of the message remains in the cache. The receiver that consumes the expired
cached copy will receive an exception when it tries to complete that message. By default, the
message lock expires after 60 seconds. This value can be extended to 5 minutes. To prevent the
251
consumption of expired messages, the cache size should always be smaller than the number of
messages that can be consumed by a client within the lock time-out interval.
When using the default lock expiration of 60 seconds, a good value for
SubscriptionClient.PrefetchCount is 20 times the maximum processing rates of all receivers of the
factory. For example, a factory creates 3 receivers. Each receiver can process up to 10
messages per second. The prefetch count should not exceed 20*3*10 = 600.By default,
QueueClient.PrefetchCount is set to 0, which means that no additional messages are fetched
from the service.
Prefetching messages increases the overall throughput for a queue or subscription because it
reduces the overall number of message operations, or round trips. Fetching the first message,
however, will take longer (due to the increased message size). Receiving prefetched messages
will be faster because these messages have already been downloaded by the client.
The time-to-live (TTL) property of a message is checked by the server at the time the server
sends the message to the client. The client does not check the message’s TTL property when the
message is received. Instead, the message can be received even if the message’s TTL has
passed while the message was cached by the client.
Prefetching does not affect the number of billable messaging operations, and is available only for
the Service Bus client protocol. The HTTP protocol does not support prefetching. Prefetching is
available for synchronous and asynchronous receive operations.
Scenarios
The following sections describe typical messaging scenarios and outline the preferred Service
Bus settings. Throughput rates are classified as small (<1msg/s), moderate ( ≥1msg/s,
<100msg/s) and high (≥100msg/s). The number of clients are classified as small (≤5), moderate
(>5, ≤20), and large (>20).
High-throughput queue
Goal: Maximize throughput of a single queue. The number of senders and receivers is small.
• To increase the overall send rate into the queue, use multiple message factories to create
senders. For each sender, use asynchronous operations or multiple threads.
• To increase the overall receive rate from the queue, use multiple message factories to create
receivers.
• Use asynchronous operations to take advantage of client-side batching.
252
• Set the batching interval to 50ms to reduce the number of Service Bus client protocol
transmissions. If multiple senders are used, increase the batching interval to 100ms.
• Leave batched store access enabled. This increases the overall rate at which messages can
be written into the queue.
• Set the prefetch count to 20 times the maximum processing rates of all receivers of a factory.
This reduces the number of Service Bus client protocol transmissions.
Benchmarks suggest that a single queue can achieve a message throughput of up to 2000msg/s
(message size: 1KB). To obtain higher throughput, use multiple queues.
253
• Use the default batching interval of 20ms to reduce the number of Service Bus client protocol
transmissions.
• Leave batched store access enabled. This increases the overall rate at which messages can
be written into the queue or topic.
• Set the prefetch count to 20 times the maximum processing rates of all receivers of a factory.
This reduces the number of Service Bus client protocol transmissions.
254
• Leave batched store access enabled. This increases the overall rate at which messages can
be written into the topic.
• Set the prefetch count to 20 times the maximum processing rates of all receivers of a factory.
This reduces the number of Service Bus client protocol transmissions.
Benchmarks suggest that a single topic with 5 subscriptions can achieve a message throughput
of up to 600msg/s (message size: 1KB) if all messages are routed to all subscriptions. To obtain
higher throughput, use multiple topics.
Exception Categories
The messaging API generate exceptions that can fall into the following categories, with the
associated action you can take to try to fix them:
255
1. User code error (System.ArgumentException, System.InvalidOperationException,
System.ObjectDisposedException,
System.Runtime.Serialization.SerializationException). General action: try to fix the code
before proceeding.
2. Setup/configuration error
(Microsoft.ServiceBus.Messaging.MessagingEntityNotFoundException,
System.UnauthorizedAccessException. General action: review your configuration and
change if necessary.
3. Transient exceptions (Microsoft.ServiceBus.Messaging.ServerBusyException,
Microsoft.ServiceBus.Messaging.MessagingCommunicationException). General action:
retry the operation or notify users.
4. Other exceptions (Microsoft.ServiceBus.Messaging.MessagingException,
System.Transactions.TransactionException, System.TimeoutException,
Microsoft.ServiceBus.Messaging.MessageLockLostException/Microsoft.ServiceBus.M
essaging.SessionLockLostException). General action: you generally do not handle these
exceptions to perform cleanup or aborts. They might be used for tracing.
Exception Types
The following table lists messaging exception types, and their causes, and notes suggested
action you can take.
System.TimeoutEx The server did not respond to the Check the Retry might
ception requested operation within the system state for help in some
specified time which is controlled by consistency and cases; add retry
Microsoft.ServiceBus.Messaging. retry if logic to code.
MessagingFactorySettings.Operati necessary.
onTimeout. The server may have
completed the requested
operation.This can happen due to
network or other infrastructure
delays.
System.InvalidOpe The requested operation is not Check the code Retry will not
rationException supported on the current state of the and the help.
object. documentation.
Microsoft.ServiceBus.Messaging.B Make sure the
rokeredMessage.Complete will requested
generate this exception if the operation is
message was received in valid.
ReceiveAndDelete mode.
256
Exception Type Description/Cause/Examples Suggested Action Note on
automatic/imme
diate retry
System.ObjectDis An attempt is made to invoke an Check the code Retry will not
posedException operation on an object that has and make sure it help.
already been closed, aborted or does not invoke
disposed.In rare cases, the ambient operations on a
transaction is already disposed. disposed object.
System.Argument • One or more arguments supplied Check the calling Retry will not
Exception to the method are invalid. code and make help.
System.ArgumenN • The URI supplied to sure the
ullException Microsoft.ServiceBus.Namesp arguments are
aceManager or correct.
System.ArgumenO
Microsoft.ServiceBus.Messagi
utOfRangeExcepti ng.MessagingFactory.Create(S
on ystem.Uri,Microsoft.ServiceBu
s.Messaging.MessagingFactor
ySettings) contains path
segment(s).
• The URI scheme supplied to
Microsoft.ServiceBus.Namesp
aceManager or
Microsoft.ServiceBus.Messagi
ng.MessagingFactory.Create(S
ystem.Uri,Microsoft.ServiceBu
s.Messaging.MessagingFactor
ySettings) is invalid.
• The property value is larger than
32KB.
Microsoft.Service Entity associated with the operation Make sure the Retry will not
Bus.Messaging.Me does not exist or it has been deleted. entity exists. help.
ssagingEntityNotF
oundException
257
Exception Type Description/Cause/Examples Suggested Action Note on
automatic/imme
diate retry
Microsoft.Service Client is not able to establish a Make sure the Retry might
Bus.Messaging.Me connection to the Service Bus. supplied host help if there are
ssagingCommunic name is correct intermittent
ationException and the host is connectivity
reachable. issues.
Microsoft.Service Service is not able to process the Client may retry Client may retry
Bus.Messaging.Se request at this time. the operation. after certain
rverBusyExceptio interval. If a
n retry results in a
different
exception,
check retry
behavior of that
exception.
Microsoft.Service Lock token associated with the Dispose the Retry will not
Bus.Messaging.Me message has expired or the lock message. help.
ssageLockLostEx token is not found.
ception
Microsoft.Service Lock associated with this session is Abort the Retry will not
Bus.Messaging.Se lost. Microsoft.Servi help.
ssionLockLostExc ceBus.Messagi
eption ng.MessageSes
sion object.
258
Exception Type Description/Cause/Examples Suggested Action Note on
automatic/imme
diate retry
value types
of the
properties
and only use
supported
types.
259