duplex http binding
TRANSCRIPT
-
8/22/2019 Duplex Http Binding
1/20
1
DuplexHttpBinding: Callback Contracts
in the Cloud with a Custom WCF Channel
ContentsIntroduction Duplex over HTTP. ................................................................................................................. 2
Callbacks in WCF ....................................................................................................................................... 2
Fundamental Design Goals of DuplexHttpBinding ....................................................................................... 3
WCF Channel Model Basics: Channel Shape and Callbacks over HTTP ........................................................ 4
Channels Have Shape.............................................................................................................................. 4
4 Types of Application Messages .............................................................................................................. 5
Why is Polling Necessary? ......................................................................................................................... 6
Smart Polling ............................................................................................................................................... 6
PollingInterval, PollingReplyInterval ......................................................................................................... 7
Starting, Stopping and Adjusting Polling Based on the Applications Needs............................................ 7
Message Batching ..................................................................................................................................... 9
Server and Client Queue Throttles.......................................................................................................... 10
A Word about WCF Channels and Sessions ................................................................................................ 11
DuplexHttpBinding Quick Reference .......................................................................................................... 11Client Binding Properties ........................................................................................................................ 11
Server Binding Properties ....................................................................................................................... 12
DuplexHttpPollingBehavior ..................................................................................................................... 13
Sample Server Configuration File ............................................................................................................ 13
Sample Client Configuration File ............................................................................................................. 14
The Sample Application .............................................................................................................................. 15
Quick Start ............................................................................................................................................... 15
Alert Service ............................................................................................................................................ 16
WindowsHost .......................................................................................................................................... 17
WindowsClient ........................................................................................................................................ 18
Silverlight 2 and Duplex Over HTTP. ........................................................................................................... 19
Additional Resources .................................................................................................................................. 20
-
8/22/2019 Duplex Http Binding
2/20
2
Introduction Duplex over HTTP.Modern applications achieve their full potential by combining rich, highly intuitive user experiences withflexible networking capabilities. They are no longer restricted to data and services that are available
only on the local machine or local network, but instead rely on loosely coupled external services that
may be located anywhere on the internet. In addition to the ability of an application to make requests
of external services, there often exists the need for these services to send unsolicited messages directly
to the application. This ability for a client application and a service to independently send each other
messages is known as the duplex message exchange pattern. Unfortunately duplex communication is
hard to achieve using the internets ubiquitous HTTP networking protocol because HTTP enables a client
application to easily send a request to a service, but the service does not have the ability to freely send
requests to the client. This paper and sample code introduce a custom extension to .NETs messaginginfrastructure to address the complexity of enabling duplex over HTTP.
Callbacks in WCF
Windows Communication Foundation (WCF) is the messaging subsystem in the .NET platform that
enables a wide range of message-based communication scenarios. WCF supports duplex
communication by enabling a higher level programming model that allows a service to invoke methods
on the client directly. This is implemented by using metadata to identify an interface known as the
callback contract. The client application hosts an object that implements the callback contract and after
the client calls at least one operation on the service, the service can capture a pointer to the client and
then invoke operations on the callback contract whenever it wants to without having to wait for the
client to initiate the communication. The clients responsibility is to simply keep the communication
channel open. In keeping with WCFs terminology, this paper will use the term callback to refer to this
ability for a service to send a message directly to a client. A typical usage pattern for callbacks is to
implement an event notification mechanism. For example, a weather monitoring service could notify a
subscribed client application that the temperature has dropped below freezing without the client
having to continually ask the service what the current temperature is.
Callbacks are a very powerful capability, but out of the box WCF only enables this duplex messaging
pattern when the client can be directly contacted via a known network address, such as when the client
application is running inside a corporate network. Using the bindings that ship with WCF, a client out in
the cloud that is connected to the internet but sitting behind a firewall cannot receive WCF callback
messages from a service unless a hole is opened in the firewall to explicitly allow it. Therefore,
applications built to take advantage of WCFs duplex communication capabilities are limited to specific
network scenarios.
DuplexHttpBinding is a sample implementation of a custom WCF binding and protocol channel that
overcomes this limitation. It enables a .NET application to leverage the WCF callback programming
-
8/22/2019 Duplex Http Binding
3/20
3
model when connected to a WCF service over the internet - using the familiar HTTP protocol on the
default port 80.
There are many application scenarios where DuplexHttpBinding will be useful. Outlook, although not an
application that uses WCF for communication, is a familiar example. Messages are pushed directly to
Outlook from the Exchange server when it is on the corporate network and this messaging patterncontinues to work when outside the corporate network because Outlook automatically switches to a
different connection protocol. Like Outlook, a .NET application using WCF could automatically switch
from the NetTcpBinding when on the corporate network to the DuplexHttpBinding when out in the
cloud. Application code does not have to be written to support the different network scenarios.
WPF XBAP applications are another scenario where the DuplexHttpBinding will be useful. An XBAP
(XAML Browser Applications) is a type of WPF client application that is characterized by its web-like
deployment mechanism. XBAPs are rich WPF client applications that are launched and hosted by a
browser. Due to restrictions imposed by the partial trust default security context that XBAPs run in,
they can only communicate with WCF services over the HTTP transport and they are not typically
directly addressable by a WCF service. The DuplexHttpBinding will allow XBAPs to leverage the full
capabilities of WCF callback contracts in partial trust.
This paper will walk through the architecture, design and implementation details of the
DuplexHttpBinding custom WCF binding and its underlying custom protocol channels that provide the
implementation. It is assumed the reader has both an understanding of how WCF enables the duplex
programming model via its support of callback contracts and an entry level understanding of the WCF
channel model. Please refer to the resources at the end of this paper to learn more about these topics
if necessary.
Fundamental Design Goals of DuplexHttpBindingThe following are the design goals for this custom WCF binding:
1. DuplexHttpBinding must provide a WCF channel stack that enables the duplex messageexchange pattern (I.E. supports WCFs Callback contract programming model).
2. DuplexHttpBinding must provide a WCF channel stack that communicates over the internet(HTTP on port 80), without requiring any additional network or firewall configuration.
3. DuplexHttpBinding must work in a partial trust .NET application, such as a WPF XBAPapplication.
4. DuplexHttpBinding must be a configuration alternative to the TCP based NetTcpBinding,enabling an application to use the most appropriate communication protocol for the current
network scenario (I.E. inside the firewall or outside the firewall).
-
8/22/2019 Duplex Http Binding
4/20
4
WCF Channel Model Basics: Channel Shape and Callbacks over HTTPIn order to understand how the DuplexHttpBinding works, it is necessary to review the role that channel
shape plays in exposing the messaging capabilities of a specific transport and how this factors into the
design of this custom binding.
Channels Have ShapeThe WCF platform has been architected in 2 fundamental layers known as the service model and the
channel model. The service model enables the friendly programming environment for developing
services and service clients; it is the service model that exposes WCFs callback capabilities to the
application developer. Below the object oriented programming environment provided by the service
model is the channel model - this is where the details of the messaging protocols are implemented and
messages are read from and written to the wire. A fundamental construct in the channel model is the
channel stack, which is a series of .NET classes called channels. Channels are arranged in a stack such
that only the top channel in the stack is exposed to the application. Messages are processed in the
channel model by being passed through the channel stack, where at the bottom they are read from and
written to the network.
In order for the service model to support the duplex message exchange pattern as implemented via the
callback programming model described above, both the service and the client must have the ability to
freely send each other messages. This ability to freely send and receive messages is exposed to the
service model by the channel stack it is using to process the messages. So therefore the channel stacks
on both the client and the server must support duplex communication. A WCF channel stack that
supports duplex implements the IDuplexChannel interface and is thus said to have the duplex channel
shape.
The IDuplexChannel interface has a Send() method and a Receive() method. The service model pushesall outbound messages through the channel stack via the Send() method and it reads all inbound
messages from the channel via the Receive() method. Now, of course the channel stacks ultimate
responsibility is to read and write messages to the underlying network, so the network protocol must be
capable of allowing both the client and the service to send and receive. Connection oriented network
protocols such as TCP and named pipes support this type of network I/O and this is why channel stacks
created by WCFs NetTcpBinding and NetNamedPipeBinding classes can support callbacks.
In contrast to the connection oriented nature of TCP and named pipes, the HTTP protocol does not
support the ability for the server to freely send messages to the client. HTTP is a request/reply protocol
which means a client can send a request to the server and receive a reply in response, but the service
cannot send a request to the client. The service can only listen for incoming requests and respond to
those requests with a reply message. The request/reply message exchange pattern is implemented in
WCF channels with the IRequestChannel interface on the client side and the IReplyChannel interface on
the server side. Unlike IDuplexChannel, the IRequestChannel interface does not have a Send() or a
Receive() method, instead it has a Request() method that takes the message to be sent as a parameter
and returns a message as the reply. Similarly, the service sides IReplyChannel interface also does not
have a Send() or Receive() method, but instead it has a ReceiveRequest() method which returns a
-
8/22/2019 Duplex Http Binding
5/20
5
message and provides a mechanism to allow the service to send back the reply to that message. A
commonly used WCF binding that supports the HTTP protocol is the BasicHttpBinding, but
unfortunately, because its channel stack is a request/reply shape and not a duplex shape, it does not
support callbacks.
The goal of the custom DuplexHttpBinding class is to support callbacks over HTTP. It therefore needs toimplement a channel stack that looks to the service model like it is a duplex channel even though the
HTTP transport channel that it is using to do network I/O does not support duplex communication.
On the client side, the channel at the top of the channel stack created by the DuplexHttpBinding is the
custom HttpPollingRequestChannel. HttpPollingRequestChannel is an IDuplexChannel that, as the name
implies, establishes communication with the WCF service by sending internal polling messages through
the HTTP transport channel below it in the stack. Because this HTTP transport channel is not a duplex
channel but is instead an IRequestChannel, it is said that the HttpPollingRequestChannel shifts its
shape from IDuplexChannel to IRequestChannel.
On the service side, the top channel in DuplexHttpBindings channel stack is the custom
HttpPollingReplyChannel. HttpPollingReplyChannel is also an IDuplexChannel that shifts shape to an
IReplyChannel. As an IReplyChannel, it listens for the internal polling messages sent by the client and
uses the reply to those messages as its opportunity to deliver all outbound messages from the server to
the client.
To put it another way: these internal HTTP requests and their associated replies sent from the client to
the server provide the vehicle for transporting the applications SOAP messages and enable the channel
to fool the service model into thinking that the server can send messages directly to the client
whenever it wants to.
4 Types of Application Messages
A key to understanding how this channel works to enable callbacks is to remember that a WCF channel
just works with messages. The service model layer provides all of the magic that transforms a method
call into a message (known as serialization) on the sender and then transforms a message into a method
call on the receiver (known as deserialization). In the case of an IDuplexChannel, the channel model is
responsible for implementing the Send() and Receive() methods in a way that ensures that the messages
make their way back and forth between the client and the service. There are essentially 4 types of
application messages being sent through the WCF channel in an application that supports the duplex
message exchange pattern:
1. Messages that result from the client invoking a method on the service contract. These aremessages sent from the client to the service.
2. Messages that result from the service operations return value. These are messages sent fromthe service to the client.
3. Messages that result from the service invoking a method on the clients callback contract. Theseare messages sent from the service to the client.
-
8/22/2019 Duplex Http Binding
6/20
6
4. Messages that result from the client callback operations return value. These are messages sentfrom the client to the service.
The client application (usually the WCF service model layer) calls Send() on the channel to send
messages 1 and 3 to the service, and the client application calls Receive() on the channel when it is
ready to accept messages 2 and 4 from the service. Conversely, the service application calls Send() onthe service side channel to send messages 2 and 4 to the client and it calls Receive() on the service side
channel when it is ready to accept messages 1 and 3 from the client.
As channel model developers, it is safe from this point on to pretty much forget about what about the
application is doing and simply get down to the business of implementing the Send() and Receive()
methods. As you explore the sample code, resist the urge to care about what the service model and/or
the application are doing with the messages and it will be easier to understand.
Why is Polling Necessary?
When the service calls Send() on the channel stack to send a message to the client, the channel cant
actually send the message directly to the client at that time - because the client and server are using
HTTP to communicate. The only way for the service channel to get messages to the client channel is to
send them out as the reply to an inbound request. So, the Send() implementation puts the outbound
message in a queue and returns. As far as the application knows, the message is on its way. The client
side channel has the responsibility of sending polling requests to the service on a regular interval to
pick up any messages that are waiting in that queue. In addition to the internal polling messages being
sent from the client channel to the service channel, the client application will also be sendingreal
application messages to invoke operations on the service contract. The service side channel has to
hand these real application messages up to the service model in response to the service model calling
Receive() on the channel stack. But regardless of whether the message received from the client was a
real application message or an internal polling message, the service channels reply to an inbound
message is used as the vehicle to send any outbound messages waiting in the queue.
An internal channel strategy that relies on polling can of course lead to an inefficient use of network
bandwidth and server resources. If implemented incorrectly it can also result in high latency, making
the application feel sluggish. Many techniques are available to make the polling as efficient as possible.
The next section will discuss in more detail the strategy for how the polling scheme is implemented and
how the application developer can affect the polling behavior.
Smart PollingPolling has the potential to add a lot of unnecessary network activity. Most of the complexity of this
custom channels implementation is the result of logic attempting to make the polling as efficient as
possible.
-
8/22/2019 Duplex Http Binding
7/20
7
PollingInterval, PollingReplyInterval
Increasing the frequency that polling messages are sent to the server will make the application more
responsive because there will be less latency between when the service sends messages and when the
client actually receives them. But this will also lead to wasted network round trips when there are no
messages on the server waiting to go to the client. The polling frequency is controlled by a configuration
property called PollingInterval. A popular technique known as long polling can reduce unnecessary
round trips. With long polling, the service side channel receives the polling request and if no messages
are waiting to go back to the client, it hold the connection open for a specified amount of time, waiting
until it has a message to send back as the reply. This greatly reduces the network traffic and decreases
message latency, but can cause a strain on precious server connection resources. The interval that the
server will hold a connection open while waiting for a reply is controlled by a configuration property
called PollingReplyInterval. The trick is to balance the PollingInterval and the PollingReplyInterval as
appropriate for the application, the network resources and the server resources.
The PollingInterval however is only a suggestion. The client and service channels communicate with
each other by sending custom headers in the SOAP message. If the client channel learns that there are
more messages waiting to go at the server, it will not wait on the PollingInterval, but will immediately
turn around and send another polling request. This continues until the service channel has no more
messages waiting in its queue.
In a similar manner, the PollingReplyInterval is only a suggestion. The PollingReplyInterval is configured
on the client, providing the ability for different clients communicating with the same service to be
configured independently. But the service has the final say in how long it will hold open expensive
network connections. The service channel has a MaxPollingReplyInterval configuration property to
support this.
Starting, Stopping and Adjusting Polling Based on the Application s Needs
In addition to adjusting the polling interval and the polling reply interval with configuration properties,
the polling behavior can also be affected by the applications messaging requirements.
When a client application invokes an operation on a service that returns a value, the client application
expects and waits for a return message from the service. The client channel can peak at that outbound
message and learn that the application is expecting a return message. Until that return message has
arrived, the client channel will not wait on the PollingInterval to send the polling messages required to
pick up that reply. Instead it will behave as it does when it knows the server has messages waiting to
send and continue sending polling requests as quickly as it can until all outstanding expected replies
are back from the service (or until the message times out). This enables the polling interval to be set
longer to more lazily poll for the unexpected callback messages without sacrificing response time for
replies to service operations.
It addition to this simple polling interval adjustment, it often makes sense to consider other aspects of
the applications needs when trying to optimize the channels polling behavior. A common application
pattern uses WCF duplex communication for implementing an event mechanism where the client will
-
8/22/2019 Duplex Http Binding
8/20
8
invoke a service operation to subscribe to an event and invoke a different service operation to
unsubscribe from that event. While subscribed, the service could be sending event notifications directly
to the client. In this pattern, the client channel only has to be continuously sending polling messages if
the application is currently subscribed. If it is not subscribed, the service will not be sending any
unsolicited messages so there is no need to poll for them.
For example, an application that helps a wine vineyard owner manage her operation might leverage a
weather service to retrieve weather conditions. The weather service provides a Freeze Alert that the
client can optionally subscribe to. Perhaps the application is configured to subscribe to the freeze alert
in the winter months but not in the summer. When the application is not subscribed, there is no need
for the channel to poll. The weather service has 2 operations that enable subscribing to freeze alerts,
the FreezeAlertSubscribe() and FreezeAlertUnsubscribe() methods. These are the triggers that need to
start and stop polling.
The custom DuplexHttpPollingBehavior attribute can be applied to the operations on the service
contract to enable this behavior thus allowing a service operation to start polling, stop polling, or adjust
the polling interval.
Consider the following contract for this sample weather service:
[ServiceContract(CallbackContract = typeof(IWeatherServiceCallback))]publicinterfaceIWeatherService{
[OperationContract][DuplexHttpPollingBehavior(PollingAction.Start, PollingInterval = "00:00:05")]void FreezeAlertSubscribe();
[OperationContract][DuplexHttpPollingBehavior(PollingAction.CorrelatedStop, StartAction = "FreezeAlertSubscribe")]void FreezeAlertUnsubscribe();
}
When DuplexHttpBindings client channel (HttpPollingRequestChannel) is processing outbound
messages, it will know that it needs to start polling when it sees that the client application is invoking
the FreezeAlertSubscribe() operation. And in this case, if the configured polling interval is currently
greater than 5 seconds, then it needs to be sped up to a 5 second interval. Adjusting the polling interval
at the operation level enables an application to speed up polling as it subscribes to more time sensitive
events.
If the HttpPollingRequestChannel subsequently sees that the application is invoking the
FreezeAlertUnsubscribe() operation, it will suspend polling.
The polling start and stop behaviors can be applied to an unlimited number of service operations. The
CorrelatedStop action in the above sample takes a StartAction parameter, which is a delimited list of
start actions. This links the stop request to a start request. Polling will only be stopped if it is currently
active and was initiated by one of these start actions and there are no other outstanding start actions.
In addition to the CorrelatedStop polling behavior, an operation can be configured with the hard Stop
PollinigAction, which will cause polling to be suspended, regardless of how it was started.
-
8/22/2019 Duplex Http Binding
9/20
9
If at least one service contract operation is configured to start polling, then by default, polling will not
start when the channel is opened. If however there are no operations configured with the
DuplexHttpPollingBehavior to cause polling to start, then polling will start by default when the channel is
opened.
The DuplexHttpPollingBehavior attribute can currently only be applied to service contract operations;applying it to callback contract operations will have no effect. It is not likely that a callback operation
would be used to start polling because the callback operation message would never have made it to
the client to begin with if polling was not already active. But more complex application scenarios that
enable callback operations to either speed up or suspend polling might make sense. This will be left as
an exercise for the developer using this sample channel. HttpPollingRequestChannel currently has some
untested and therefore commented-out code to enable this functionality.
Message Batching
As described above, each HTTP request and reply does not correlate directly to an application message;
the HTTP traffic simply provides the transport vehicle for the real application messages. As the servicesends messages to the client, they get stored in the channels queue until an HTTP request is available to
transport them to the client. If the service application is sending notifications to the client more
frequently than the client channel is sending polling requests to pick them up, then multiple messages
could exist in the service channels queue at any one time. It was described above that the client
channel will send polling messages as quickly as it can while it knows that the service queue has
messages waiting to go, but the channel can achieve even greater network efficiency and application
responsiveness by packaging up multiple messages and sending them back to the client as a single HTTP
reply. This is called message batching.
Message batching is enabled via a binding property that is used by the services
HttpPollingReplyChannel: MaxMessagesInBatch. When the service channel is preparing a reply, if there
are 15 messages waiting to go in the queue and MaxMessagesInBatch is set to 10, then 10 of the
messages will be removed from the queue and batched up into a single SOAP message to be sent to the
client. The client channel (HttpPollingRequestChannel) is then responsible for converting the batch
message back to the original 10 individual SOAP messages before returning them to the client
application in response to the Receive() method being invoked. The client channel also has a queue, an
inbound message queue, to facilitate this behavior. As described above, the client channel in this
example will learn that there are 5 more messages waiting and will therefore immediately issue another
polling request to pick them up.
Message batching enables very high performance messaging scenarios. For example, if the service is
firing notifications to the client in response to a real time hardware device, it could potentially be
sending 50 or more messages per second. The client being connected over the internet - might only
be able to get polling messages to the server every half second due to network latency. If the channel
was only able to send one message per HTTP request, it would not be able to keep up with the
applications performance requirements. Message batching solves this problem.
-
8/22/2019 Duplex Http Binding
10/20
10
It is up to the application developer to set the MaxMessagesInBatch property appropriately based on
the applications needs, the expected size of a typical application message and potentially other factors.
Server and Client Queue Throttles
Because there is not a one-to-one relationship between messages sent and received from the
application and the actual HTTP network requests and replies, both the service channel(HttpPollingReplyChannel) and the client channel (HttpPollingRequestChannel) implement internal
message queues.
As the service is sending messages, they are being dropped into HttpPollingReplyChannelsoutbound
queue to be picked up by the asynchronous logic that is processing incoming polling messages. If for
some reason the client channel is not sending polling messages, then the number of messages in this
queue would just continue to grow until the process runs out of memory. The application would
potentially not know there was a problem. To mitigate this, the binding exposes the
MaxUndeliveredMessages configuration property. When the queue reaches this configured maximum
number of messages waiting to be delivered, then subsequent attempts to add more messages to thequeue will simply wait until room is available. Eventually the Send() method will time out, and the
application will learn there is a communication problem with the channel. It is the responsibility of the
application developer to set this property to a value that makes sense for the application, given factors
such as the expected polling frequency and the expected message frequency and the configured
maximum number of messages that can be batched into a single reply.
Conversely, the client channel has an input queue because inbound messages are only received as
replies to HTTP requests and each reply could contain a batch of logical application messages. When the
client application logic calls Receive() on the channel, it wants one application message. Receive() is
implemented by simply reading the next available message from this input queue. Regardless of
whether or not the application has called Receive() to pick up a message, the polling loop is sending
requests and receiving one or more messages per reply and placing them in the queue. In the unlikely
event that the application which is the WCF service model in most cases is not calling Receive() on
the channel quickly enough, there is the potential that this inbound message queue could also get
backlogged with unprocessed messages and become a memory leak on the client.
HttpPollingRequestChannel has an internal throttle, implemented via the private field
maxMessagesInQueue, which is arbitrarily set to 500. If the clients channel does get backlogged and
reaches the max value, this will cause the client channel to fault.
The included InputQueue class is used by both channels to implement their queues. It provides
sophisticated multi-reader, multi-writer asynchronous message queuing and dequeuing capabilities.
The InputQueue class is from the HttpCookieSession custom channel sample found on MSDN in the WCF
documentation (Channels Extensibility Samples).
-
8/22/2019 Duplex Http Binding
11/20
11
A Word about WCF Channels and SessionsA WCF channel can either be sessionless or sessionful. Sessionful channels provide message
correlation on the server, so that one instance of the channel will be created and kept alive for each
client/connection. Messages received from the wire contain an indicator in the message that allows
them to be routed to the correct channel instance. A sessionful channel is required in order to
implement sessions at the service or application level. To learn more about the details of sessionful
channels, refer to the WCF MSDN topic: Choosing a Message Exchange Pattern.
In order to function properly, DuplexHttpBinding, like NetTcpBinding, needed to implement a sessionful
channel stack. A sessionful channel stacks responsibilities include establishing a protocol between the
client and the server to create and track a session identifier, instancing one channel stack per session on
the server, managing the lifetime of the session, and routing the incoming messages to the correct
channel stack instance. This is not a trivial task.
Luckily, WCF ships a sessionful channel that works with the HttpTransport that can be used to
implement sessions in the channel stack. Including the ReliableSessionBindingElement in the stack ofBindingElements created by our binding injects the ReliableSession channel in the stack. Refer to the
WCF MSDN topic: Creating a BindingElement to learn more about WCF BindingElements and their role
in the channel model.
Unfortunately, this ReliableSession channel introduces potentially unnecessary overhead because it also
provides message ordering and guaranteed delivery capabilities, which translate into additional network
traffic complicating efforts to minimize the polling traffic. Additionally, this reliable session channel
does not work in partial trust and partial trust is a design requirement for DuplexHttpBinding.
Therefore, in addition to the custom HTTP polling channel implementation, the sample application also
includes a custom HTTP session channel implementation that does work in partial trust. This sample
HTTP session channel is only a slightly modified version of theHttpCookieSessionsample found in the
WCF SDK on MSDN. Instead of using HTTP cookies, the HttpSession sample included here uses a custom
SOAP header to track the session ID.
The application developer using this sample code can choose to use either the included custom
HttpSession channel, or WCFs ReliableSession channel. The DuplexHttpBinding has a Session
configuration property that can be either set to HttpSession or ReliableSession. The only restriction
is that both the client and the server must both use the same type of session.
DuplexHttpBinding Quick Reference
Client Binding Properties
DuplexHttpBinding.Sessiono Type: Microsoft.Samples.DuplexHttp.SessionType (enum)o Enum values: ReliableSession, HttpSession
http://msdn.microsoft.com/en-us/library/aa751829.aspxhttp://msdn.microsoft.com/en-us/library/aa751829.aspxhttp://msdn.microsoft.com/en-us/library/aa751829.aspxhttp://msdn.microsoft.com/en-us/library/aa751786(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/aa751786(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/aa751786(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/ms751405(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/ms751405(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/ms751405(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/ms751405(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/aa751786(VS.85).aspxhttp://msdn.microsoft.com/en-us/library/aa751829.aspx -
8/22/2019 Duplex Http Binding
12/20
12
o Remarks: Sessions are required. Use the property to tell the binding to use either WCFsReliableSession channel or the included custom HttpSession channel. Both the client
channel and the server channel must use the same session type.
DuplexHttpBinding.PollingIntervalo Type: System.TimeSpano Remarks: The default duration the client channel will wait after receiving a reply before
sendinganother polling request. The actual polling interval is a combination of runtime
factors.
DuplexHttpBinding.PollingReplyIntervalo Type: System.TimeSpano Remarks: The duration the server will hold the polling request open while waiting for
messages to send back to the client as the reply. Can be overridden by the server with
the MaxPollingReplyInterval property. If this duration expires and there are still no
messages to be sent to the client, the server will return an empty reply. The polling
requests timeout property is coordinated with this duration such that if a reply is not
received by the PollingReplyInterval plus 3 seconds (arbitrary, adjust in the sample code
as needed), the polling request will time out and the channel will fault.
Server Binding Properties
DuplexHttpBinding.Sessiono Type: Microsoft.Samples.DuplexHttp.SessionType (enum)o Enum values: ReliableSession, HttpSessiono Remarks: Sessions are required. Use the property to tell the binding to use either WCFs
ReliableSession channel or the included custom HttpSession channel. Both the client
channel and the server channel must use the same session type.
DuplexHttpBinding.MaxUndeliveredMessageso Type: System.Int32o Remarks: Maximum number of outbound messages that the channel will hold in its
outbound message queue. If the client is not sending polling messages frequently
enough, the outbound message queue will potentially become backed up. If there is no
room in the queue, the Send() method will potentially time out while waiting for space.
DuplexHttpBinding.MaxMessagesInBatcho Type: System.Int32o Remarks: Maximum number of outbound messages that will be batched into a single
reply. When the channel is preparing a reply message, if there is more than one
message waiting in the outbound message queue they will be batched into a single
message for transport to the client.
DuplexHttpBinding.MaxPollingReplyIntervalo Type: System.Int32o Remarks: Maximum duration the channel will hold the HTTP polling request open while
waiting for messages to be sent to the client as the reply. Note that only one
-
8/22/2019 Duplex Http Binding
13/20
13
connection will be help open. If no messages are available when the duration expires,
an empty reply will be sent back to the client.
DuplexHttpPollingBehavior
This is an attribute to be applied to operations on the service contract. It will trigger the channel to
start or stop polling and optionally adjust the polling interval. If at least one operation is configured withthis attribute as a start polling action, the client channel will not automatically start polling by default.
It will instead wait for one of the polling start operations to be invoked before starting to send polling
messages. If no operations on the service contract are configured as polling start operations, then the
client channel will start polling by default when the channel is opened.
The DuplexHttpPollingBehavior enables the channel to coordinate turning polling on and off with a
typical subscribe/unsubscribe application metaphor.
Properties:
DuplexHttpPollingBehavior.PollingActiono Type: Microsoft.Samples.DuplexHttp.PollingAction (enum)o Enum values: Start, Stop, CorrelatedStopo Remarks: The PollingAction property is required and is provided in the constructor.
Start will cause polling to start when the operation is invoked. Stop will cause polling to
stop when the operation is invoked. CorrelatedStop will cause polling to stop when the
operation is invoked if it was started by the operation(s) indicated in the StartAction
property and there are no other outstanding start operations.
DuplexHttpPollingBehavior.PollingIntervalo Type: System.Stringo Remarks: Must be a valid string format that will parse to a System.TimeSpan. Relevant
only if the PollingAction is Start. This is not a required parameter, but if provided, it will
be used to fine tune the polling interval at runtime. If the current polling interval is
longer than this duration, it will be sped up to this value.
DuplexHttpPollingBehavior.StartActiono Type: System.Stringo Remarks: Semi-colon delimited list of server contract actions. Used in conjunction with
the CorrelatedStop polling action. Each action can either be a fully qualified start action
or an action shortened to just the method name.
Sample Server Configuration FileThe following partial server config file sections are included here for reference:
-
8/22/2019 Duplex Http Binding
14/20
14
Culture=neutral,PublicKeyToken=null" />
Sample Client Configuration File
The following partial client config file sections are included here for reference:
-
8/22/2019 Duplex Http Binding
15/20
15
The Sample ApplicationThe sample code includes a reference application that demonstrates how to use the custom
DuplexHttpBinding. The reference application consists of an alert service, a service host application and
a client application. The alert service provides a simple engine that enables clients to subscribe to and
post alerts, which are simple string messages.
The DuplexHttpAll.sln Visual Studio solution contains the following 5 projects:
1. DuplexHttpBinding: This builds the DuplexHttpBinding.dll, which contains the custom bindingand channels.
2. AlertService: This contains the alert service implementation, which includes the AlertServiceweb service and the Alerts engine.
3. AlertServiceContract: This builds the AlertServiceContract.dll. It includes the IAlertService andIAlertServiceCallback contracts. These service contracts are separated to their own assembly so
they can be shared by the service and the client.
4. WindowsClient: This builds WindowsClient.exe, the alert client WPF application.5. WindowsHost: This builds WindowsHost.exe, a WPF application that serves as the console for
the alert service as well as the host process for the alert web service.
Quick Start
Run the Sample0. Start Visual Studio on Vista using Run as Administrator (required for the service host
application to listen for connections)
1. Press F5 in Visual Studio to launch both the WindowsClient and WindowsHost applications.2. Click Create Proxy in the blue Alert Client application to connect with the alert service.3. Click on the Red alert subscriptions check box to subscribe to red alerts. This first interaction
with the service will open the channel and start polling. The trace output will indicate that
polling messages are being sent to the service.
4. In the green Alert Server Console and Service Host application, click on the Post Red button.This will cause a red alert to be posted, and because the client is subscribed to red alerts, the
new red alert will show up in the Red Alerts list box in the client.5. In the client, click on the Yellow alert subscriptions check box to subscribe to yellow alerts.6. In the client, enter a new yellow alert in the text box and click Post Yellow. This will post a new
alert to the service. The alert you entered will show up in theYellow Alerts list box in the green
server console application and because the client is subscribed to yellow alerts, it will also show
up in the Yellow Alerts list box on the client.
-
8/22/2019 Duplex Http Binding
16/20
16
Things to Notice
1. Regular polling doesnt start (no trace messages) until the client subscribes to either red oryellow alerts.
2. If only yellow alerts are subscribed, polling messages will be sent from the server every 4seconds. This is because the bindings default polling interval is set to 4 seconds.
3. If subscribed to red alerts, polling messages will be sent from the server every 1 second. This isbecause the SubscribeRed() server operation is configured to adjust the polling interval to 1
second.
4. Because the polling reply interval is set to 10 seconds, each polling message sent to the serverwill be held open by the channel for up to 10 seconds while waiting for any messages to be sent
back to the client. If there is no activity, this will result in an additional 10 seconds between
polling requests.
Alert Service
The alert service and callback contracts look like this:
publicinterfaceIAlertService
{[OperationContract(IsOneWay=true) ]void PostAlert(AlertType type, string alert);
[OperationContract]string[] GetAllAlerts(AlertType type);
[OperationContract(IsOneWay = true)][DuplexHttpPollingBehavior(PollingAction.Start)]void SubscribeYellow();
[OperationContract(IsOneWay = true)][DuplexHttpPollingBehavior(PollingAction.CorrelatedStop,StartAction= "SubscribeYellow")]void UnsubscribeYellow();
[OperationContract(IsOneWay = true)]
[DuplexHttpPollingBehavior(PollingAction.Start,PollingInterval="00:00:01")]void SubscribeRed();
[OperationContract(IsOneWay = true)][DuplexHttpPollingBehavior(PollingAction.CorrelatedStop,StartAction= "SubscribeRed")]void UnsubscribeRed();
[OperationContract(IsOneWay = true)][DuplexHttpPollingBehavior(PollingAction.Stop)]void UnsubscribeAll();
}
publicinterfaceIAlertServiceCallback{
[OperationContract(IsOneWay = true)]
void AlertPosted(AlertType type, string alert);}
There are 2 types of alerts: yellow alerts and red alerts. A client can subscribe to either type
independently. Because the SubscribeRed() method has a PollingInterval specified in the
DuplexHttpPollingBehavior attribute, when a client application using the DuplexHttpBinding subscribes
to red alerts the internal polling messages will speed up to a frequency of every 1 second (unless the
-
8/22/2019 Duplex Http Binding
17/20
17
polling interval of course is already faster than 1 second.) When an alert is posted to the service, all
subscribed clients will have their AlertPosted() callback method invoked.
Instead of using SvcUtil.exe to generate a client proxy for the service, the client application uses WCFs
generic DuplexChannelFactory class to create the client proxy. This was done simply to remove the
extra developer step of invoking SvcUtil.exe to generate a new client proxy each time the interface wasrefactored during development. Client proxies can be generated with SvcUtil.exe for use with this
binding.
The app.config files for the WindowsClient and WindowsHost projects contain the WCF binding
configuration settings as described above, but the user interfaces for the client and service applications
enable all of these important settings to be adjusted as well.
WindowsHost
The WindowsHost application serves 2 purposes. It hosts the alert engine and it hosts the WCF alertservice to provide client access to the alerts engine. In addition to hosting the alerts engine, it provides
a user interface for the engine, essentially acting as a server side alerts console. Looking at the screen
shot above, there are 3 main panes in the application:
1. Service Configuration Pane.
-
8/22/2019 Duplex Http Binding
18/20
18
On the left is a pane that enables adjusting the WCF binding properties. All of these properties
are described above in the Smart Polling section of this paper. When WindowsHost is started,
it will automatically start the web service on 3 different endpoints, 2 of them listening on HTTP
using the DuplexHttpBinding and one listening on TCP using WCFs NetTcpBinding. To change
any of the binding properties via this interface, first stop the service using the Stop Service
button.
2. Trace Output Pane.The service and channel Trace.WriteLine messages are piped to this pane. This text box is
editable which can be convenient while testing the application and running the channel through
various scenarios.
3. Alert ConsoleThe top right portion of the window contains the user interface for the alert engine. Enter an
alert in either the red or yellow text box and click the appropriate post button to post the alert.
As alerts are posted, they are displayed in either the Yellow Alerts or Red Alerts list box and
the alert engine will fire an event indicating that an alert was posted. The hosted WCF alert
service is subscribed to this alert engines event, the WCF alert service will respond by pushing
the alert out to all subscribed clients, by invoking the AlertPosted() method on the callback
contract.
WindowsClient
-
8/22/2019 Duplex Http Binding
19/20
19
The alert client application provides the user interface to post and subscribe to alerts. It demonstrates
all of the capabilities of the custom WCF channel except its ability to run in partial trust (because this is
a full trust application). There are 3 main panes in the application:
1. Proxy Configuration.Use the Proxy Configuration panel to configure the settings used for connecting to the webservice. First choose either the TCP (NetTcpBinding) or HTTP (DuplexHttpBinding) binding. If
using the HTTP binding, choose which channel to use to provide session support.
ReliableSession equates to WCFs ReliableSession channel and HttpSession causes the custom
HttpSession channel to be used (read the section above on sessions to learn more about these
choices). The Polling Interval and Polling Reply Interval settings are configured in seconds (read
the section above on Smart Polling to understand their purpose). Click Create Proxy to
generate a client proxy with the configured settings. To adjust the settings, close the proxy and
create a new one after making the changes.
2. Trace Output.The client and channel Trace.WriteLine messages are piped to in this pane. This text box iseditable which can be convenient while testing the application and running the channel through
various scenarios.
3. Alert User Interface.After clicking Create Proxy, use the Post and Get buttons in the interface to interact with the
alert service. To subscribe to either red or yellow alerts, check the appropriate Alert
Subscriptions check box.
The sample application is designed to demonstrate the channels abilities to invoke request/reply
methods on a service, invoke one-way messages on a service and support one-way callbacks from the
service. It does not demonstrate callback methods that return a reply value to the sender.
Silverlight 2 and Duplex Over HTTP.As of this writing, Silverlight 2 Beta 2 is shipping with a WCF channel that enables the duplex message
exchange pattern over HTTP. The client binding PollingDuplexHttpBinding - will be included in the
Silverlight plug-in. The Silverlight SDK contains a .NET 3.5 channel for use by the service. Please refer to
the Silverlight SDK for more details on how to use this channel. This Silverlight solution does not
currently include a client channel for .NET clients.
Although similarly named DuplexHttpBinding and PollingDuplexHttpBinding, these 2 channels were
developed independently. DuplexHttpBinding is provided as sample code demonstrating how to solve
this problem by extending the WCF channel model, it has a different API and different capabilities from
the Silverlight channel that is soon to be shipping with Silverlight.
Like the DuplexHttpBindings channels, this new Silverlight channel is an IDuplexChannel so it will be
able to be used in place of this sample code if it eventually shows up in the .NET framework.
-
8/22/2019 Duplex Http Binding
20/20
20
Additional Resources
Duplex programming in WCF:http://msdn.microsoft.com/en-us/library/ms731064.aspx WCF Channel Model Overview:http://msdn.microsoft.com/en-us/library/ms729840.aspx Duplex Services in Silverlight: http://msdn.microsoft.com/en-us/library/cc645026(VS.95).aspx Comet Long Polling :http://en.wikipedia.org/wiki/Comet_%28programming%29
http://msdn.microsoft.com/en-us/library/ms731064.aspxhttp://msdn.microsoft.com/en-us/library/ms731064.aspxhttp://msdn.microsoft.com/en-us/library/ms731064.aspxhttp://msdn.microsoft.com/en-us/library/ms729840.aspxhttp://msdn.microsoft.com/en-us/library/ms729840.aspxhttp://msdn.microsoft.com/en-us/library/ms729840.aspxhttp://msdn.microsoft.com/en-us/library/cc645026(VS.95).aspxhttp://msdn.microsoft.com/en-us/library/cc645026(VS.95).aspxhttp://en.wikipedia.org/wiki/Comet_%28programming%29http://en.wikipedia.org/wiki/Comet_%28programming%29http://en.wikipedia.org/wiki/Comet_%28programming%29http://en.wikipedia.org/wiki/Comet_%28programming%29http://msdn.microsoft.com/en-us/library/cc645026(VS.95).aspxhttp://msdn.microsoft.com/en-us/library/ms729840.aspxhttp://msdn.microsoft.com/en-us/library/ms731064.aspx