duplex http binding

Upload: cccrosss

Post on 08-Aug-2018

215 views

Category:

Documents


0 download

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