Friday, December 04, 2009

What Happened to the ESB MSMQ Adapter Provider?

In our current, project we built an itinerary that utilized the Business Rules Engine (BRE) to set an endpoint to the MSMQ Adapter. Lo and behold, there was no MSMQ Adapter provider, until now, Below is our source code for cheating the Adapter Provider framework for building a custom MSMQ Adapter Provider. The code was simple and to the point. No explanation necessary…

Source Code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Practices.ESB.Adapter;

using Microsoft.BizTalk.Message.Interop;


 


 

namespace Tellago.ESB.AdapterProviders

{

/// <summary>

/// Ths class implements IAdapterProvider for setting the context properties of

/// the BTS MSMQ adapter. Loaded by the AdapterMgr class

/// </summary>

public class MSMQAdapterProvider : BaseAdapterProvider

{

public override string AdapterName

{

get { return "MSMQ"; }

}


 

public override void SetEndpoint(Dictionary<string, string> ResolverDictionary, IBaseMessageContext msg)

{

base.SetEndpoint(ResolverDictionary, msg);

}


 

public override string AdapterContextPropertyNamespace

{

get

{

return "http://schemas.microsoft.com/BizTalk/2003/msmq-properties";

}

}


 

protected override void SetEndpointContextProperties(IBaseMessageContext pipelineContext, string endpointConfig)

{

base.SetEndpointContextProperties(pipelineContext, endpointConfig);


 

string[] properties = endpointConfig.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);


 

foreach (string property in properties)

{

string[] data = property.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);

string key = data[0];

string value = data.Length < 2 ? "" : data[1];


 

pipelineContext.Write(key, this.AdapterContextPropertyNamespace, value);

}

}


 

public override void SetEndpoint(Dictionary<string, string> ResolverDictionary, Microsoft.XLANGs.BaseTypes.XLANGMessage message)

{

base.SetEndpoint(ResolverDictionary, message);

}


 

protected override void SetEndpointContextProperties(Microsoft.XLANGs.BaseTypes.XLANGMessage message, string endpointConfig)

{

base.SetEndpointContextProperties(message, endpointConfig);

}


 

protected override void SetContextProperties(IBaseMessageContext pipelineContext, Dictionary<string, string> ResolverDictionary)

{

base.SetContextProperties(pipelineContext, ResolverDictionary);

}


 

protected override void SetContextProperties(Microsoft.XLANGs.BaseTypes.XLANGMessage message, Dictionary<string, string> ResolverDictionary)

{

base.SetContextProperties(message, ResolverDictionary);

}

}

}

Steps to use:

1. Rebuild and GAC this project

2. Open the ESB.Config file from the install folder

Add the following line in the Adapter Providers section:

    <adapterProvider name="MSMQ" type="Tellago.ESB.AdapterProviders.MSMQAdapterProvider, Tellago.ESB.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c0eafbe4dc54c287" moniker="msmq" />

    

Happy ESBng!!!    

Saturday, November 14, 2009

Moving Blog posts to WordPress: http://dgoins.wordpress.com

Everyone, I'll be moving my blogging site over to WordPress, it can be found here:

http://dgoins.wordpress.com

Monday, October 12, 2009


How to Turn On ESB 2.0 Tracing...


If you're building a BizTalk ESB 2.0 Solution, there will come a time where you need to use custom traces and the built in ESB 2.0 Traces to help debug and track what is going on.

The way to turn on tracing for ESB 2.0 is to create a Trace Source, set the TraceSwitch to "Verbose" for the Trace Source and configure a trace listener to record the traces. That's all.

Below are the steps to do what was just mentioned:

1) Open the BizTalk Configuration file
BTSNTSVC.exe.config

2) Modify the file to contain to contain a "< system.diagnostics >" section inside the "< configuration >" element. (Verify one does not already exists because two diagnostic sections will cause the BizTalk Host instance to fail)
< system.diagnostics >

3) Inside the Diagnostics section add a source with the name: "BizTalk ESB Toolkit 2.0" (Make sure that this source does not conflict with any other sources otherwise your BizTalk Host Instance won't start.) The ESB 2.0 Toolkit is hardcoded to check for this source name before logging any details.
< sources >
< source name="BizTalk ESB Toolkit 2.0" />
< sources >

4) Inside the Diagnostics section also add a Trace Switch with the name of "BizTalkESBToolkit" sets its value to "4" or "Verbose". This trace switch is used to determine when to log or write traces, only if the value is Verbose.
< switches >
< add name="BizTalkESBToolkit20" value="4" />
</switches >

5) Add a Trace listener. If you don't already have a trace listener configured, add 1 of the many Trace listeners that come out of the box with the .Net framework: (Default, EventLog, TextWriter, Console, Text, etc.) When using the EventLogTraceListener, the initializeData attribute must be set to the source of the Tracing Event. In this case it is the "BizTalk ESB Toolkit 2.0" source.
<trace autoflush="true" indentsize="4" >
<listeners >
<add name="myListener" type="System.Diagnostics.EventLogTraceListener" initializeData="BizTalk ESB Toolkit 2.0" />
</listeners>
</trace>

Complete View of the BizTalk Configureation File

6) Restart BizTalk Host Instance and Wahlah!!!

ESB 2.0 Toolkit Traces

Tuesday, September 22, 2009

Controlling where Maps are processed with BizTalk ESB 2.0
(Canonical Messaging Pattern)


While implementing some ESB patterns, my team and I at Tellago were tasked with purposely running a map after the message gets published to the Message Box. Which brings up the topic of this post. If you want to control where in the processing steps a map is transformed, let's say on the receiving side, or on the sending side, we can do this with the "Routing Slip" pattern for ESB aka Itineraries.

Before I get into how this is done, let me explain why you may need to do so. One reason could be you simply want to follow a Canonical Message Exchange Pattern. Where Endpoint specific messages are transformed into a common canonicalized format. A formart in which you control and process. After processing, you may need to transform the message back into an endpoint specific format that only the endpoint understands.

The way in which we accomplished this was to apply a Transformation service before after the publishing to the Message box. In ESB 2.0 itinerary design, a Transformation step is applied before the off ramp extender and another is applied after, which the post transformation step having its container set to the Send Port/Send Off Ramp as outlined in the following Itinerary design:



This design allows for a message to come into BizTalk using one format, then transformed into a canonical format, processed and routed to a subscribing endpoint. At which point in time the message gets published to the message box. Any subscribing endpoint would then receive a copy of this message and could further process the routing slip steps. How this works is that the Itinerary is promoted into the Message context for each message copy. You can also do other forms of processing, such as normal BizTalk processing like orchestrations or other send ports.

In order to continue processing the itinerary steps after the Off ramp extender, all you need is a component that understands the itinerary that can be found inside the message context. This could be a send port with a send pipeline which contains an ESB Dispatcher component. To process the steps inside a custom orchestration, use the ESB Itinerary Utility classes to get the current step. In anycase this pattern allows for multiple steps to occur after the message is published to the message box.


Happy ESB'ng
Using the latest BRE Deployed Policy with ESB BRE Resolver...

Quick note, over the weekend I noticed that when you select a version number for a rule within the BRE Resolver inside an itinerary, it uses the specified version of a policy. If you want to allow the BRE Resolver to utilize the latest deployed version, leave the version number blank.




A colleague of mine Leandro Diaz Guerra verfied this, where he states:
"I just wanted everyone to know that you can configure the itinerary BRE Resolver for both transformation & routing services leaving policy version empty, and it will automatically run the rules with the latest deployed version, just like the Itinerary Selector in the ItinerarySelect receive pipeline."

Friday, July 31, 2009

ESB – BRE – BTS 2009 – Breaking Changes to be aware of…


While the new BTS 2009 has major improvements in its support for TFS, MS Build within it’s project structure, there was a breaking change to the Business Rule Engine Composer Schema Import process. In BizTalk Server 2004, and 2006, when importing a BizTalk Schema into the Business Rule composer, you had to be aware of the fact that the Composer did not get the Document Type property assigned correctly.




When importing the schema you had to verify the value of this property matched the fully qualified name of the .Net Schema class type.




If it did not, you must manually type it in. For BizTalk Server 2006 R2, this process was *sort of* fixed.

The way the R2 import process works is that the BRE Composer searches for a BizTalk Project file within the same directory of the Schema file. If it finds one, the import process opens the BizTalk project file, which is nothing more than an xml file, and looks for the Files section until it matches the schema name and pulls the Document Type property value from the Namespace and Root node name.





Well obviously BizTalk Server 2009 changed its project (Xml File structure) design to match MS Build project file formats, hence the support for TFS. The New format uses MS Build Item Groups, which are pointers to file locations for a Project setting.



The Business Rule Composer was not updated to refresh where the Document Type property value is pulled from, thus causing the Business Rule policies not to execute properly when using BizTalk Server 2009 and ESB 2.0.


By the way, the R2 version of the project structure still works, so theorectically, if you add a CData section to the 2009 project structure and add the Files ->Include->File sections as outlined above, then the Document Type will be pulled correctly.

So the point is- remember to manually edit the Document Type in the Business Rule Composer when using with BizTalk Server 2009 and ESB.

Sunday, May 24, 2009

What good is the BAM WCF Interceptor???

A colleague and I were discussing the difference between BizTalk default BAM interceptors and the WCF/WF BAM interceptors. The question came up as to what specifically can theBAM WCF provide that the default Pipeline interceptors can't.

Well I will first start with the overall purpose. The purpose of the BAM WCF Interceptor is to allow WCF Services and WCF Clients to take advantage of the BAM infrastructure. WCF Services and Clients can update BAM Checkpoints (KPI’s) for an already deployed BAM Activity Definition. It essentially can record the same data as the Receive and Send Ports of the BizTalk BAM Tracking profile. However, there are a few additions to the WCF Interceptors that the Receive and Send Ports cannot accomplish. For example, the WCF interceptor can record Client and Service Faults, Channel Faults and other conditions that can occur within the WCF Channel layer. Also, the WCF Interceptor can use XPath to navigate the message and parameters, to record plethora of aggregated values such as getting a “Sum”, “Avg”, “Min”, “Max”, or “Count” of repeating items. Any valid xpath expression can be used with the only limitation being that if an Xpath returns multiple nodes, only the first node out of the collection is used.

Wednesday, May 20, 2009

Tales from the Developers Crypt:
(Another one of those postings that never made it from about a year ago...)

Hosting XAML only workflows services in ASP.NET

Recently I was tasked with building a lab that showed how to build a XAML only based WCF service and host it inside of ASP.NET for the purpose of following the SOA pillar of service composition, and agility. I always taught that this could be done; quite frankly I have even heard various colleagues say this could be done. However I never actually saw it implemented, thus the reasoning for this blog. Below I describe the pains and glories of hosting declarative marked-up Xaml based workflows. My intention is that you read through this simple check list in hopes that you won’t run into any ‘gotchas’ when you implement this. So happy workflowin!!!

The easiest way to pass in a Xaml file is to use the WorkflowServicehostFactory inside a ASP.NET “.svc” file. All you have to do is apply the “service=”Filename.xoml” attribute and away you go… Well almost.
Depending on your XOML, you may need to include TypeProviders, something that can’t be done simply pointing to a XOML file, thus using this approach I was blocked. To solve this issue, I had to create my own XamlWFHostFactory class by simply deriving from the WorkflowServiceHostFactory class and overriding the CreateServiceHost method with code such as this:
public class XamlWFHostFactory : WorkflowServiceHostFactory
{
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{

TypeProvider typeProv = new TypeProvider(System.Web.HttpContext.Current);
typeProv.AddAssembly(System.Reflection.Assembly.GetExecutingAssembly());
typeProv.AddAssemblyReference("MovieFlowService.dll");

}
}
Once I had my typeProviders, any custom code behind or references to classes that exist inside other .Net assemblies can be resolved. However I didn’t come to this conclusion right away.

Simply passing in a XOML file caused all kinds of errors, however I only saw one inside the browser when testing the WF/Service was XAML validation failed. Now prior to trying the host the XOML file inside the WorkflowServiceHostFactory, my workflow ran fine with a custom windows form based host. I just knew that the XOML file was fine and that the validation was a generic error.
So I said, this is no problem, I’ll just listen for the WF validation errors and write them out to an ASP.NET Trace. What I learned immediately for debugging is that there is no way to get the validation errors on the WorkflowServiceHostFactory, because the error events are caught by the internal WorkflowServiceHost that the factory creates by default. The default host isn’t bubbling up the events to the WorkflowServiceHostFactory where my Event handling code is listening thus I had to create my own WFHost. This was done easily enough by creating a class that derives from the WorkflowServiceHost and overrind the InitializeRuntime to listen for the WorkflowValidation errors:
Public class XamlWFHost : WorkflowServiceHost
{
public XamlWFHost(string wfPath, string rulesPath, ITypeProvider provider, Uri[] baseaddresses ): base (wfPath, rulesPath, provider, baseaddresses )
{ }

protected override void InitializeRuntime()
{
try
{
// HttpContext.Current.Trace.Warn("Trace is good- InitializeRuntime()");
base.InitializeRuntime();
}
catch (WorkflowValidationFailedException ex)
{

StringBuilder errors = new StringBuilder();
foreach (System.Workflow.ComponentModel.Compiler.ValidationError error in ex.Errors)
{
errors.AppendLine(error.ToString());
}
string errMsg = "Validation Errors: " + errors.ToString();
Debug.WriteLine(errMsg);
System.Web.HttpContext.Current.Trace.Write(errMsg);
}
}
In the overriden InitializeRuntime() method and catch the ValidationErrors here because they are not caught by default within your HostFactory. Also if something goes wrong with your WCF ServiceHost, like your channel faults for some reason it’s also not a bad idea to listen for the HostFaulted event as well. From WCF I’ve learned that when you set a break point inside the Faulted event method, you can see all the exceptions that have occurred from WCF's perspective.
Something else to note, when trying to write out Trace statements to the ASP.NET Trace context, found inside the HttpContext, it was null. The reason being was that WCF was not turned on to support ASP.NET compatibility, nor was the web configuration enabled to support this. This is equivalent to turning on all the ASP.Net intrinsic such as tracing, Request, Response, Sessions state and etc. You don’t need to turn on ASP.Net compatibility to use WorkflowServices, in my case I wanted to write out details simply out to the Browser using the TraceContext inside of ASP.NET.
To use the System.Web.HttpContext. we must specify in WCF to use the ASP.NET compatibility which posed another problem. The ASP.Net compatibility is enabled using a ServiceBehavior. Well first off, how do I get to the ServiceHost, after all this is a WorkflowServiceHost not simply a WCF ServiceHost.
Well that’s the answer, the WorkflowServiceHost allows you to access the description and ServiceEndpoints as if you’re working with the ServiceHost class yourself. In fact the workflow service host derives from the ServiceHostBase class. So just add the behaviors you’d like. Also if you wanted to access the workflow runtime, as long as you’ve configured a behavior for it such as within the configuration file upon startup:






You can access it inside of code such as this:

WorkflowRuntimeBehavior wfrBehavior =
wfSvcHost.Description.Behaviors.Find();
WorkflowRuntime wfr = wfrbehavior.WorkflowRuntime;

So going back to the ASP.NET compatibility issue, we can add this behavior through the ASPNetCompatibility attribute inside code such as this code here:
AspNetCompatibilityRequirementsAttribute behavior = new AspNetCompatibilityRequirementsAttribute();
behavior.RequirementsMode = AspNetCompatibilityRequirementsMode.Required ;
wfSvcHost.Description.Behaviors.Add(behavior);
As I was going through my code, I also noticed that in order to use the TypeProvider classes, I needed to pass in either null, or a class that implements the IServiceProvider interface. It just so happens the the System.Web.HttpContext actually implements this interface.
Some last pointers about hosting XOML Inside an ASP.NET workflowServiceHost, I had several problems when using Root names inside the XOML that contained some combination of NS.Class as the root node name. I also found that in order to get it to work properly, the Root node name inside the XOML file had to match the name of Root Activity, and the namespace prefix matched namespace within XmlDefinitionsAttribute inside the Host project assemblyinfo.cs file.


Inside you Hosting project inside the AssemblyInfo.cs file make sure that the ns0: prefix matches within the assemblyInfo XmlnsDefintion attribute:
[assembly: System.Workflow.ComponentModel.Serialization.XmlnsDefinition("clr-namespace:MovieFlowService", "MovieFlowService")]
Also note: that when using a custom host, I can leave off the Assembly part, while here inside the workflow service host, this didn't work when I left off the Assembly=... part off.
Another issue I ran into was that if you build the WF using the VS.NET WF designer with XAML separation, verify that within the WF Service Properties page you change the NameSpace.ServiceName to simply ServiceName, which should match the Xaml Root node name. Also make sure that this Servicename, and Xaml Root name all match the ServiceName inside the web.config for the WCF Service Model configuration.
Finally after all this was done, I came across another simple but really good and appreciated error, ASP.Net didn’t have permissions to read my XOML file from the disk. After adding the proper permissions, restarting the IIS App Pool and IIS respectively, VIOLA!!!! My XAML only workflow hosted within WCF through ASP.Net and the workflowServiceHostFactory.
How The BizTalk WCF Send Adapter works under the hood.

This posting is a follow up to the WCF Receive Adapter article posted last year. (Sorry it took so long, I wrote it at the same time of the Receive adapter article however it was never posted...)

The WCF Adapter can send messages to a WCF Service, effectively making the WCF Send Adapter a client or "Proxy" that can communicate with WCF Dispatchers “services”.

Normally in a WCF Client - Server solution, a client, or "Proxy" must match the Endpoint configuration for a Service. This means that the client must have an address, binding and contract that match the service. The client must use the same binding that the service expects. The same binding means that the client must use the same binding elements such as Security options, transactions, reliable sessions, and etc. The client must also match the same encoder-formatter and transport.

Client applications such as windows forms applications and asp.net web sites, can easily use the Add service reference utility that comes with the .Net 3.5 framework SDK. When using this utility, a proxy class is generated where a developer can simply include this auto-generated proxy class inside their solution. The WCF Send Adapter supports something similar. The WCF Send Adapter can import a WCF Configuration from a app.config-web.config file. The way to get a hold of this file is to use the SvcUtil.exe tool (Add Service Reference) and generate a proxy like normal, and uses the App.config-web.config that is generated from this tool. The way in which you use this configuration is to simply import the configuration using a WCF-Custom adapter. When you import the configuration file, the WCF creates a WCF Send Adapter configuration that matches what the Dispathcing Service expects.

But what happens to the contract attributes, such as the operation attributes like IsOneWay, TransactionFlow, and etc. These are not inside the configuration file, they are declared as attributes inside the service contract, and these must match too?

Alas, the WCF Send Adapter uses the binging configuration and options specified in each binding element to infer which attributes need to be applied to a generic contract.

The WCF Send adapters uses 2 generic service contracts- IOutputChannel, and IRequestChannel. These two interfaces are not actually marked up with the [ServiceContract] attribute however the WCF Framework at a very low level uses these interfaces to send messages. The difference between these two interfaces is simply IOutputChannel is used for One Way operations, while IRequestChannel is used for two way operations. Thus if you need to send a message and wait for a return acknowledgement from the service, the IRequestChannel will be used. This is the default for WCF Send adapters because BizTalk needs confirmation as to when to delete the message from the MessageBox DB. One way operations, a special case within BizTalk, would be used with transports such as the net.msmq bindings, where the underlying transport can send back a control message acknowledging its receipt. This control message is internal within the protocol, effectively keeping the pattern “One Way”, even though technically it’s not. Another point to add here with one way operations, WCF Send adapters do not support a Service whose contract specifies “IsOneWay=true”. The reason is quite simple, the BizTalk adapter framework needs to transactionally “commit” if the message is successfully send. Services marked with “IsOneWay=true” operations do not yield a way to determine this. No control message is sent back, thus the WCF Send adapter doesn’t support this option.

When these channels-contracts are being created, the binding configration is taken and read from SSO DB and the various attributes are dynamically added to the descriptions of either Operations or message contracts.

What's important to overstand here is that in a normal client application the client would match the contract by either sharing the service contract, or making a contract that is effectively wire compatible. Wire compatible simply means that any option can set, as long as the final output of the message contains all the appropiate elements and attributes that the Dispather can successfully process. Because the WCF Send adapters infer these settings from your configuration of a WCF Send Adapter, there is no room for error, the slightest property that is set incorrectly will cause the WCF send adapter to not successfully send data to a WCF Service. For example, just recently a colleague was trying to flow transactions across to a WCF service which was configured to NotAllow transactions to flow into it. Techinically this means that there should be no OLE or WSAT header propogating any transaction ID. The application was first tested using a Windows Client application. Within the Windows application, a transaction scope was created, and the binding used had transactions being flowed. The client proxy was sharing the Service contract of the service which specified that TransactionFlow set to NotAllowed. The Default behavior of the windows proxy client was to strip off the OLE-WSAT header information within the message, thus making it wire compatible, even though the binding options were otherwise specified. The windows client application worked successfully because the TransactionFlow attribute specified inside the proxy class caused the proxy stripped the transaction header information before being sent.

Now let's take the above scenario with BizTalk Server's WCF Send Adapters. If you use a WCF Send Adapter, there is no place where you specify how to share a contract, nor manually create a wire compatible one. It's left up to the dynamic creation of the Send Adapter using the configuration, to create a matching contract. If a binding contained the option to flow transactions, as outlined above, the WCF Send adapter would add the appropriate TransactionFlow attribute dynamically at run time. This would cause the dynamic proxy to create the OLE/WSAT transaction headers, and send them to the service. At this point, the service would yield an exception saying that the ServiceContract specified that TransactionFlow is not allowed, while the same binding options used inside a Windows Forms application works, simply because the ServiceContract is shared. To solve this challenge, the binding should specify not to flow transactions.

To be continued…
I've just officially joined the master minds of Tellago...
http://weblogs.asp.net/gsusx/archive/2009/05/12/dwight-goins-joins-tellago.aspx

First task: DELL Technican (Those who know can laugh it off...)
Second task: The Sr. BizTalk Documenter (If you only knew...)
Third task: TBD

I want to thank everyone over at Tellago for giving me this opportunity. So let's go write some code!!!

Friday, April 17, 2009

Getting The DLP-RFID1 Reader to work 0n Windows 7 build 7000(64-bit)

Well I was just sent a private message by a friend @MS who saw that I got the DLP RFID Reader/Writer to work with Vista 64 bit with a small hack. Well, the hack is not needed any more because the makers of the device driver FTDI have updated support for 64 bit. You can find the drivers here: http://www.ftdichip.com/FTDrivers.htm.

From this site I found the CDM 2.04.16.exe file that contains the updated version of the drivers.

Steps to install:
1. First plug in the DLP RFID Reader into the USB port.
2. The prompt will tell you that the driver can not be installed.
3. Next run the executable which installs the lastest drivers.
4. Open the Device Mgr, find the troubled DLP device and right-click and update its driver.
5. Choose to browse computer, and then select to install the driver from a list of installed drivers.
6. Select the FTDI as the manufacturer, then select the first option.
7. Unplug the device and plug it back in, Windows 7 should recognize it.
8. Test the device with the RFIDSample.exe application that can be found on the FTDI web site.

Hope this helps.

Wednesday, April 15, 2009

Getting SQL Dev/SQL Express DBs to talk to each other inside of VPC images

This is just a note to myself, and maybe someone else can use this tip as well...

Most of the MS MOC VPC images by default can't talk to each other, as in the case of the Sharepoint course 5060/5061 and 50064 etc.

You can make changes to the images to have them talk to each other.

1. Using VPC Console, change the network adapter to use the current Network card on the physical system.

2. Inside the VPC images configure the network card to use a dummy IP address such as 192.268.10.1, use the default Subnet Mask of 255.255.255.0 and set the DNS server address to itself such as 127.0.0.1

3. At this point verify that the Server VPC Images can browse and see each other using Windows explorer, such as if the first Server image is named "Server1", and the Second is named "Server2", then within the Win Explorer of "Server1" try to connecto to file://%20server2/ and within the "Server2" image try to connect to \\ server1 in their respective windows.

4. If all is good here, On the image that contains SQL 2005+, open the SQL Suraface Area configuration application, and select the Surface Area Configuration for Services and Connections -> Select the SQLExpress->Database Engine-> Remote Connections and select Local and Remote connections, choosing any of the available choices. (For example Using both TCP/IP and named pipes)

5. Next open Active Computers and Users/ or the Computer Management snapin, and add the account you plan to use to connect to SQL to a Windows/AD Group that you will add to the Sysadmin role in SQL/SQLExpress.

6. Next open up SQL/SQLExpress, goto the security->Role folder, and Add this Windows /AD Group to the SysAdmin sql role.

7. Next Open the Services control applet from the control panel, and restart the SQL/SQL Express service.

8. Lastly, Start the SQL Browsing service if it's not already started.

---Happy coding

Monday, March 30, 2009

Building Push Notifications using WCF Duplex binding in Silverlight v2.0/v3.0


Building Push Notifications using WCF Duplex binding in Silverlight v2.0 and v3.0

This article will explain how the WCF Duplex “Push” style architecture works inside of Silverlight. To get started a quick definition of Push needs to be explained, as well as its twin sister, Pull.
Here is the definition for Push and Pull as found on Wikipedia:
Push technology, or server push, describes a style of Internet-based communication where the request for a given transaction originates with the publisher or central server. It is contrasted with pull technology, where the request for the transmission of information originates with the receiver or client.
If I may reword the above definition for the purpose of this article and using WCF Push style notifications in Silverlight, let’s redefine the definition of “Push” to mean a style of communication where requests can originate from a receiver or a sender, as opposed to “Pull” which means for every request, it must originate with the receiver.
In the above definition I purposely leave off terms like polling, and who sends the request first and so forth, as this would easily cloud the definition of the two terms. As a side note however, usually “Pull” is associated with polling, while “Push” is not.
Doing a quick search for the Differences between Push and Pull you quickly run across many blogs, articles and examples outling each. One such study that caught my attention was a 12 page report completed by some students at Delft University of Technology explaining the pros and cons of both architectures using a non Microsoft framework. In their research they found that:
“if we want high data coherence and high network performance, we should choose the push approach. However, push brings some scalability issues; the server application CPU usage is 7 times higher as in pull. According to our results, the server starts to saturate at 350-500 users. For larger number of users, load balancing and server clustering techniques are unavoidable.” (Full 12-page report found here: http://swerl.tudelft.nl/twiki/pub/Main/TechnicalReports/TUD-SERG-2007-016.pdf)

The Push architecture that was tested used an AJAX framework with a push style methodology called COMET. I’m not going to discuss COMET versus anything Microsoft has, however what I will take a broad look at is the Microsoft approach to building a push style Rich Internet based Application, similar to AJAX, using the Silverlight Framework and the new WCF Duplex binding. Within, I’ll point out some similarities between the AJAX Comet style design outlined within the research document, and WCF “Push” style within the MS Silverlight design. This document will not attempt to provide any form of measurement, or test results as outlined within the study. This document simply serves as a practical study on how to implement the same type of architecture utilizing Silverlight and WCF’s Duplex binding.

Silverlight is Microsoft’s flagship product that rivals Adobe’s Flash technology. While Adobe Flash has the capabilities to make calls out into basic web services, and REST styled endpoints, from the time of this writing, it lacks the capability to do “Push” styled applications. The best Flash can do is provide a Pull or Polling styled design within its framework. Silverlight rivals this design with the promise to deliver “Push” style designs within its framework using WCF’s Duplex bindings, but I have to ask myself is it really “Push” or just another hidden Polling mechanism that tries its best to mimic “Push”.

For Starters, let’s discuss WCF in general and get a general overview of WCF and its Duplex communication pattern. WCF stands for Windows Communication Foundation and it is a framework for building distributed .NET applications. The framework is a part of the .NET 3.0 release with updates being applied in versions 3.5 and 3.5 service pack 1.
The WCF framework is also a part of the .NET Compact Framework 3.5, as well as the .NET Framework that ships with Silverlight v2.0. These smaller frameworks previously mentioned contain a small subset of WCF features and functionality for their respective platforms.
The full blown version of WCF has a very rich feature set and functionality. It boasts the ability to communicate with many protocols such as TCP, HTTP, UDP, SOAP, SMTP, MSMQ, NamedPipes just to name a few. It also includes the ability monitor other WCF applications using WMI, and performance counters. In addition to maintenance and health of currently running WCF applications, there is also the ability to log messages and track various events that occur during the normal processing of the WCF framework. On top of all of this WCF supports the majority of WS-Specifications such as WS-Security, WS-Addressing, WS-MTOM encoding, WS-Coordination and WS-Transactions. The point I’m driving at is that WCF is the new plumbing behind how to build distributed applications using the .NET 3.0 and above Framework. The Bottom line is if you’re building distributed software for Microsoft platforms, and you’re not using WCF today, you’re not using the right toolset.
In general WCF is broken down into a couple of different layers: the Service Model, and the messaging layer. The Service Model layer is like a software factory. It creates software or components that help a .NET Application communicate across the wire. The Service Model layer builds various messaging layer components to enforce a Service Level Agreement, found inside of contracts. These agreements contain message exchange patterns, security requirements, transaction requirements, session support, and settings such as the type of network protocol needed to send and receive data.
The Messaging layer is composed of a group of these components. Each component, also known as a channel, individually has a specific task to perform that adhere to one or more items within a Service Level Agreement. The way in which these channels measure up to the overall policy or agreement is by executing only the task assigned to it, such as encrypting a message using a specific Encryption algorithm. In order to adhere to the complete contract, there are usually many more requirements which must be in place such as which networking stack protocol should be used to send and receive data, and what is the format or encoding of the data being sent and received. This is accomplished through the use of different channels.
The Messaging layer allows for multiple channels to be placed on top of each other to provide an ordered structure as to which component/channel will run first, next and last. This ordered structure adheres to the Service Level Agreement. In WCF, this ordering is referred to as the “Channel Stack”.
The Channel Stack helps maintain and enforce a set of policies as outlined by the contract which two applications use to communicate. It also helps explain the design of the Message exchange pattern (MEP) being used for the contract. MEPs are a design that helps two systems communicate back and forth by outlining what is to be expected for receipt and transmission of data. There are many MEPs. One such MEP is known as a Datagram, which is a one –way asynchronous design. The Datagram pattern can flow one way asynchronously in any direction. It could be a one-way send, or a one-way receive. There are also the synchronous one-way send and receive patterns, where the difference is the system which sends or receives waits to get an acknowledgement back that the synchronous Send/Receive has successfully completed, or errored, as opposed to the asynchronous versions, which no acknowledgement is returned, commonly referred to as a “fire –and-forget” design. The Channel stack also supports the two-way MEP patterns commonly referred to as Request/Response and Solicit/Response in both synchronous and asynchronous forms.

In the WCF framework channels implement the MEPs through various different implementations of WCF Interfaces. WCF Supports 5 different interfaces that outline which type of MEP will be used inside a Channel. The interface implemented, also known in WCF as the “Channel Shape” determines if it will be a one-way or a two-way MEP. A declarative attribute, IsOneWay=true, helps the Service Model determine within the channel shape if the MEP will be asynchronous or synchronous. Without going into all 5 of the WCF channel shapes in depth, I will focus however on a few channel shapes in particular: IInputChannel, IOutputChannel, IDuplexChannel and IRequestChannel for comparison sake.
The IInputChannel and IOutputChannel shapes are interfaces that have very basic signatures:
public interface IInputChannel
{
Message Receive()
…[Asyncrhronous Programming model omitted for brevity]…
}

public interface IOutputChannel
{
void Send(Message msg);
…[Asyncrhronous Programming model omitted for brevity]…

}

The IInputChannel shape is used to receive messages from the transport protocol channel, which effectively reads the data off the wire. The IOutputChannel is used to send messages to the transport protocol channel, which effectively writes data on the wire for transmission. Notice that the signature of these methods is one way, being either one way receive or one way send. In case you still don’t see it, there is no way for a client trying to invoke the Receive() method, to send in any data, there are no parameters to be able to pass in any information. When sending, the same is present only this time for receipt. As a client, there is no way to get any response back when sending a message because the return value is “void”. What this boils down to is that any WCF Channel that implements one or more of these shapes will support the one-way MEP. Keep in mind however, that true asynchronous behavior requires that the executing thread not block and wait for a response. This is exactly what the IsAsync=true attribute implies. The client application’s thread invoking the Receive() or Send(Msg) methods will not block and wait for the methods to complete. This effectively means that if the Receive() or Send(Msg) methods throw exceptions the client applications will not be able to catch them.
Moving on to the IDuplexChannel. the IDuplexChannel interface is nothing more than the combination of the IInputChannel and IOutpuChannel interfaces.
public interface IDuplexChannel : IInputChannel, IOutputChannel { … }

What this boils down to is that any channel in the WCF Framework that implements this interface has the ability to do One-way Receives, independent of One-way Sends. In other words, A one way receive can occur unrelated to a one-way send, and they can happen in any order, and in any design. There is no correlation between when the Receive() is invoked and when the Send() is invoked. When we take this duplex design and apply it to both sides of the communication cable, both the sender and receiver applications have the capability to send and receive independent of the other without any special correlation or thread blocking.
Let me digress a little and revisit the authoritative definition of “Push” and “Pull”:
If I may reword the above definition for the purpose of this article and using WCF Push style notifications in Silverlight, let’s redefine the definition of “Push” to mean a style of communication where requests can originate from a receiver or a sender, as opposed to “Pull” which means for every request, it must originate with the receiver.

When we take a look at the Duplex pattern, there are no constraints placed on who sends first, who receives first, or if a send corresponds to a receive and vice versa. In a normal Request/Response pattern, the receiver of the request would send some data, expecting a response to return. Every response is constrained by a mandatory request being sent in as in the signature of the IRequestChannel design:
public interface IRequestChannel
{
Message Request (Message msg);
…(APM omitted for brevity)…
}

Shown for the sake of completion, IReplyChannel, is an interface that usually is implemented by the opposite end to respond to the IRequestChannel interface.
public interface IReplyChannel
{
RequestContext ReceiveRequest();
…(APM omitted for brevity)…
}

This brings us to the obvious point; any WCF channel that implements the IRequestChannel shape supports the “Pull” design. This however does not mean that Channels that implement the IInput/IOutput cannot support the “Pull” design. In order for the IInput/IOutput to support the “Pull” design, there needs to be some correlation and thread blocking, or synchronization between and Send and Receive. WCF supports this too. This can be done using some form of correlated thread blocking session channel. In WCF, this can also be accomplished through fairly custom, and possibly performance bloated CallbackContracts.
A CallbackContract is simply an interface that a Client implements for the purpose of handling a synchronization between client-server exchanges. The interface outlines what is expected for a server/service/sender to send, and what a client/receiver/proxy expects to receive. CallbackContracts are created by using the CallbackContract property of a ServiceContract attribute. As a service developer, you would place this attribute inside the ServiceContract like so:
[ServiceContract(CallbackContract(typeof(INotifyClient))]
public interface IDataService { … operations here … }

Where the INotifyClient is an interface defined without a ServiceContract attribute as such:
public interface INotifyClient
{
//IsOneWay makes this Asynchronous and supports Duplex MEP
[OperationContract(IsOneWay=true)]
void SendToClient(Message msg);
}

Keeping correlation in mind, for the Push design, randomly sending and receiving does not do any justice. Client “A” sending some data to Client “B” dictates in certain solutions that Client “B” needs to be aware that Client “A” is sending some information, thus even in the Duplex pattern there needs to be some form of correlation between the two. WCF Supports this through the ISessionChannel in general. There is also an IDuplexSessionChannel for supporting Duplex Sessions. And Lastly, there are Duplex CallbackContracts that supports this as well such as the INotifyClient displayed above. The difference between regular CallbackContracts, and Duplex supported is simply the IsOneWay=true property on the Operation contract. When you leave this off, extra acknowledgement messages are sent back and forth creating a chatty like behavior and eventually degrading performance.

Now that we’ve discussed a little on what Push is, and how WCF Implements Push Style architecture with Duplex channels, what is available in Silverlight to provide the capability to do Push Style notifications?

Silverlight v2.0 contains a small subset of WCF features and components. Within this feature and component set, there is support for Channels, Channel Factories, and Bindings: basically the messaging layer constrained to specific network protocols. There is no support for the ServiceModel. This design is very similar to WCF for the .NET Compact Framework. What this means is that there is no support for reading a configuration file in Silverlight and having the ServiceModel dynamically build the channel stack. While there’s nothing stopping you from coding this yourself, it’s not included out of the box.

WCF for Silverlight supports only one network protocol channel: HTTP/HTTPS. This means that you can’t use TCP, UDP, MSMQ, NamedPipes or any of the other cool network protocols mentioned earlier with the WCF framework for Silverlight. Don’t be alarmed however; Silverlight does support TCP using the .NET TCP Socket classes, which also support building push style solutions.

Another thing that’s not included in this release of WCF for Silverlight are the WS-* channels that support WS-Coordination, WS-Transactions, WS-Security and the likes. So this means there is no support for using any of the predefined channel stacks known as “Bindings” that come with WCF as well, such as the WSHttpBinding.

So you may be wondering if all the cool things of WCF are removed in WCF for Silverlight what’s left?

Update: Silverlight v3.0 promises new updates in its support for WCF. A scaled down service model will be available for reading configuration files, a new new binary encoder for performance, support for WS-Security specifications, and syntax enhancements to make building WCF Duplex bindings easier.

WCF for Silverlight supports the Basic HTTP binding for WCF, and only SOAP version 1.1 with no Addressing, and Basic Security is also supported using Transport layer security. But this is basic stuff.

The cool support I want to bring to your attention is a new server side WCF predefined binding, as well as the clientside Silverlight binding, that gets installed when you install Silverlight: the PollingDuplexHttpBinding. Don’t let the name fool you. Even though it says: PollingDuplexHttpBinding, it’s still push architecture simply by the authorized definition of “Push”. Threre’s polling on the server side, and polling on the Client side. However on the Silverlight client side the polling is occurring in the network layer using the WS-MC (Make Connection standard). On the server side, the polling is just to check the session timeout which occurrs less frequently than the client. This polling architecture is due in part to the limitation of the HTTP transport protocol, and constraints within the current version of Silveright. HTTP will not allow for a server to listen on a separate address within the same connection as in the TCP protocol, and Silverlight will not allow for a mini HTTP listener within its engine which would allow for a http addressable endpoint for communication, thus, the reason for the WS-MC implementation, and polling architecture. This is also the reason for the statement:
“Silverlight rivals this design with the promise to deliver “Push” style designs within its framework using WCF’s Duplex bindings, but I have to ask myself is it really “Push” or just another hidden Polling mechanism that tries its best to mimic “Push”.”

The binding is nothing more than a Duplex BasicHttpBinding, that removes support for the WS-* specifications. It does however add support for the WS-MC (MakeConnections) standard. In WCF there are quite a few Duplex bindings, one in particular is a WSHttpDual binding that supports Duplex communication using the WS-*, Session, Security, Transaction mechanism. This binding cannot be used with Silverlight simply because Silverlight for WCF doesn’t support any WS-* channels. So theoretically you can build a WCF service using a Custom binding that contains a Http Channel, with a Text Encoder, a Duplex Channel, and a Custom Session Channel that removes the WS-ReliabileMessaging tags, and adds the ability to store the “pushed” messages from the server to an internal queue which a client uses to “pull/poll” and retrieve, as well as support for WS-MC, and you have it, the PollingDuplexHttpBinding.

The WS-MakeConnection standard is a specification for the transfer of messages between two endpoints when the sending endpoint is unable to initiate a new connection to the receiving endpoint, as in the case with the HTTP protocol when a client sends a requests to the server and unexpectedly or purposely disconnects before the server can send the response back. This specification defines a mechanism to create a new connection by uniquely identifying non-addressable endpoints, and a mechanism by which messages destined for those endpoints can be delivered. It also defines a SOAP binding that is required for interoperability. (http://docs.oasis-open.org/ws-rx/wsmc/200702/wsmc-1.1-spec-os.html)
The Server Polling Mechanism
The PollingDuplex Binding has a timer mechanism on the server that checks or polls to see if the client is still connected. By default the server waits 10 minutes and then closes the session, and connection. If a client application sends a WS-MC request within the 10 minute timeout, the session resets itself to another 10 minutes from the time it received the WS-MC. Each session is is stored within an in memory dictionary collection by its session ID. If the session is timed out or no activity has transpired, and no activity means, there are no ws-mc messages flowing to and from the client to the service, not the standard RPC operations that are called from the client to the service, then the session is removed from the list, the current channel is faulted and its connection is closed. This timeout setting can be controlled by the by setting the InactivityTimeout property on the PollingDuplexHttpBinding instance in code in the service.
When we take a look at the AJAX COMET style implementation, its design is somewhat different. It too polls for a timeout. It sends a message to the client to verify if the client is still connected, not requiring the client to send a request first, and it too has a model that can control the timeout a client should check for which helps controls how often a client needs to poll for data, thus there is a form of polling implemented here as well.

The PollingDuplexHttpBinding requires either an IDuplessSessionChannel or IReplyChannel in order to create and open the Channel Stack for sending and receiving messages, again showing you the Push style design. The IReplyChannel is basically what the server side polling mechanism uses to reply asynchronously to a client WS-MC request. The reply can be three types of messages: A Successful response to the WS-MC request, an HTTP error code message, or a custom message defined by the CallbackContract for the purpose of sending data down to the client. When the service needs to send a message to the client, the binding queues the message by session id, and simply dequeues the message when the client polling WS-MC request comes in.

On the server side, to build a service that supports sending data to and from a Silverlight WCF Duplex binding, you’ll need to use the Server side PollingDuplexHttpBinding located inside a particular assembly found at %Program Files%\Microsoft SDKs\Silverlight\v2.0\Librarries\Server\System.ServiceModel.PollingDuplex.dll. What makes this assembly so special is that the assembly is built referencing the Full .NET 3.5 Framework. In addition to this, the PollingDuplexSessionChannel in this assembly does not implement a ChannelFactory, only a ChannelListener. The ChannelListener will only support a IduplexSession shape, or the IreplyChannel shape. This effectively means that the WCF Service will only listen to receive messages with a duplex session, or send data as Responses to Requests from the WS-Make Connection call, or through a customized callback, as built from a CallbackContract.
This is where the standard definition of “PUSH” gets a little fuzzy. In this design, WCF for Silverlight requires that a client send a request as a WS-MC message internally, as a polling request, in order for it to receive the Message from the Service. However what makes this design still follow the authoritative definition is that a Silverlight Designed Duplex Service does not need every request originating from a receiver in order to respond. It can respond at will, by simply sending messages to the message queue per session id. This will work as long as the message originates inside an operation context so that the callback instance is still valid. The Message/Responses will simply be placed on a queue, until the next client polling interval, which at that time the Message is dequeued and sent to the client.

The Client Pushing Mechanism

The client also creates a PollingDuplexHttpBinding instance in code, however its design is slightly different. On the client side, it is the opposite. The PollingDuplexHttpBinding can be found at %Program Files%\Microsoft SDKs\Silverlight\v2.0\Librarries\Client\System.ServiceModel.PollingDuplex.dll. This assembly references all of the Silverlight specific assemblies and will only work in a Silverlight v2.0 project. The PollingDuplexSessionChannel class found in this assembly does not implement a ChannelListener. Instead it implements a ChannelFactory for sending requests, and a ChannelDispatcher that starts the polling mechanism controlled by the ClientPollTimeout property. This polling mechanism sends a WS-MC using the IRequestChannel to the Server.
If we revisit the IRequestChannel, you’ll recall that it returns a Message from the method signature. This message can either be a custom message that eventually gets unwrapped as a call into a custom class implementation of the CallbackContract, or simply a message for you to parse. In any case you have a choice.

This is where it’s important to understand the true meaning behind one-way versus two-way MEPs. In this two-way MEP for the IRequestChannel, the client will do a thread block if built using a synchronous design. In this case the implementation of this two-way MEP is an asynchronous design, which in Silverlight means we would invoke this on a different thread usually called the “worker” thread, than the “Main” UI thread. This also means that the blocking “worker” thread will wait for an indeterminate amount of time, or one that is specified again by the ClientPollTimeout property. How long the thread waits for the client poll request will also be affected by how long the server takes to respond to the poll request. The Server binding contains a ServerPollTimeout property that allows us to address this as well. By Default this is set to 15 seconds, on the server. This basically means that the if there are no Messages from the queue to return, at most the server has up until 15 seconds to return a response. If a response if found in the queue or a basic empty WS-MC message with an HTTP Status code message is successfully created and returned, the channel stays open otherwise a fault is thrown and the connection is terminated. This process occurs until a session timeout, or the connection to the open channel stack are explicitly closed through the Channel Factory on the client.

This may be a little too much to take in all at once, and in reality, you don’t really need to know all these things happen under the hood. You just really need to know how to build a Client that can support the Duplex binding, and how to build a WCF Service that knows how to communicate with a Silverlight Client.

Creating The Client Code
To Create a Polling channel you would write code such as this inside a Silverlight application:
PollingDuplexHttpBinding pushChannel = new PollingDuplexHttpBinding();
//Still follow disconnected designs here keep the connection polling time low…
pushChannel.InactivityTimeout = TimeSpan.FromMinutes(1);
IChannelFactory channelStack = pushChannel.BuildChannelFactory (new BindingParameterCollection());
channelStack.BeginOpen(new AsyncCallback(onChannelsOpen), channelStack);

One thing to note when working with WCF in Silverlight, is that it can be very daunting, simply because Silverlight forces the developer to follow UI coding best practices. Best practices such as always update a UI control from the Main controlling thread, as opposed to some worker thread. Silverlight forces this constraint internally as it checks whenever you try to do so. The reason I say this is because usually you invoke services on separate threads so as not to block your UI from performing. When you do this you’ll need to update your controls on the main thread only otherwise you’ll get an InvalidOperationException thrown from Silverlight.

There are many ways to handle this, one way is by using a SynchronizationContext. Another way is by using Callback and events, or a combination of both the context and the callbacks. Even so another method a colleague of mine pointed out is using the method shown here (http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx). You create a method to do whatever main thread ops you need, and call it from all threads. The method itself checks whether or not it needs to re-invoke itself from the UI thread to do the updates. Either way, a good amount of code will need to be written and a good understanding of the .NET Asynchronous Programming Model (APM) will be required in order to do this.

Using the SynchrnoizationContext is fairly straight forward. The first thing you would do is create a class level variable to hold the state of the current ThreadContext:
SynchronizationContext _currentThreadContext = null;
The next thing you would do is gather the current thread before making the service invocation call on a separate thread such as code like this:
_currentThreadContext = SynchronizationContext.Current;
The above line of code gives you a pointer to the main thread context, which allows you to make a callback into the main thread using a callback delegate for the purpose of updating a UI control. Here’s an example:
void onComplete(IasyncResult ar)
{
IduplexSessionChannel pushChannel = (IduplexSessionChannel)ar.AsyncState;
pushChannel.EndSend(ar);
_currentThreadContext.Post(UpdateUI, “Sending Complete”);
}

void UpdateUI (object msg)
{
silverLightTextBox.Text = (string)msg;
}


Creating the Service Code
The steps to build a WCF Service that supports Silverlight Duplex clients are straight forward. The first step is to create a Service Contract of your choosing that serves as the main Service Level Agreement you want to expose. Below is an example:
[ServiceContract(Namespace=”http://www.quicklearn.com/ChatService”)]
public interface IChatService
{
[OperationContract(Action=”RegisterClient”, IsOneWay=true)]
void RegisterClient (string clientName);

[OperationContract(Action=”SendMessage”, IsOneWay=true)]
void SendMessage(Message msg);

[OperationContract(Action=”UnRegisterClient”, IsOneWay=true)]
void UnRegisterClient(string clientID);
}

The next thing to do is to create a Client Callback interface for the purpose of sending data back to a client:
//No service contract here… only operation contract
public interface INotifyClient
{
[OperationContract(Action=”NotifyClient”, IsOneWay=true)]
void NotifyClient (Message msgToClient);
}

Once the Callback contract is created, add its type definition to the ServiceContract attribute as such:
[ServiceContract(Namespace=”http://www.quicklearn.com/ChatService”, CallbackContract=typeof(INotifyClient))]
public interface IChatService
{ … }

Next you implement the Service Contract in an Implementation class:
public class ChatService : IChatService
{

public static IDictionary clients = new Dictionary();
public static StringBuilder ChatWindow = new StringBuilder();

#region IChatService Members

public void RegisterClient(string clientName)
{
Guid g = Guid.NewGuid();
clients.Add(clientName, g);
//notify client that they have been registered
INotifyClient client = OperationContext.Current.GetCallbackChannel();
client.NotifyClient(Message.CreateMessage(MessageVersion.Default, "NotifyClient", string.Format("{0} has been registered with clientID: {1}", clientName, g.ToString() )));
}

public void SendMessage(System.ServiceModel.Channels.Message msgFromClient)
{
//Add to the Chat window buffer
string msg = msgFromClient.GetBody();
ChatWindow.Append(msg);
INotifyClient client = OperationContext.Current.GetCallbackChannel();
client.NotifyClient(Message.CreateMessage(MessageVersion.Default, "NotifyClient", ChatWindow.ToString()));

}

public void UnRegisterClient(string clientID)
{
clients.Remove(clientID);
INotifyClient client = OperationContext.Current.GetCallbackChannel();
client.NotifyClient(Message.CreateMessage(MessageVersion.Default, "NotifyClient", string.Format("{0} has been un registered", clientID )));

}

#endregion
}

To access the client callback, you use the OperationContext.Current.GetCallbackChannel() method call. This callback will only be available inside an operation context. This means that it is only available in the context of an instance of a Operation marked as a Operation Contract. Private methods, will not have access to this, neither will any other method. Trying to pass this item through private method calls will not work because the context will be switched and thus render the OperationContext null.

Once the implementation is complete, you’ll need a service host that knows how instruct the ServiceModel how to create an endpoint which contains the Service Level Agreement, and the PollingDuplexHttpBinding to work with Silverlight.

I’ll host this service inside of IIS/ASP.NET and I’ll use a configuration file that uses the PollingDuplexHttpBinding configuration. This configuration can tell the default WCF ServiceHostFactory to create a ServiceHost that reads the configuration for building a SLA and PollingDuplexHttpBinding. To do this create a new Web site based off the WCF Service Application template and change the “Service1.svc” file to use the ChatService class create earlier.

Also change the web.configuration file to use configure the “ChatService” along with changing the contract to say IChatService found on the endpoint.

The last thing we need to do is to change the binding from WsHttpBinding to PollingDuplexHttpBinding. The only issue here is that the developers didn’t create this binding as an Configuration Binding element, which means there is not registration for this binding to be used within a configuration file. So to use it inside a configuration file, I’ll just create a custom Binding class and wrap its functionality for the purpose of using it inside a configuration file. Then I’ll register it using the Advanced tab inside the WCF Configuration editor.

To create the wrapper classes, create a class that derives from the StandardBindingCollectionElement, and another class that derives from the StandardBindingElement abstract class. Override the InitializeFrom and onApplyConfiguration methods, and override the BindingElementType property. Below provides the sample code:
public class PollingDuplexHttpElementCollection : StandardBindingCollectionElement
{
public const string SECTIONNAME = "pollingDuplexHttpBinding";
public static PollingDuplexHttpElementCollection GetBindingCollectionElement()
{
PollingDuplexHttpElementCollection collElem = null;
BindingsSection sect = ConfigurationManager.GetSection("system.serviceModel/bindings") as BindingsSection ;
if (sect != null)
{
collElem = sect[SECTIONNAME] as PollingDuplexHttpElementCollection;
}
return collElem;
}
}


public class PollingDuplexHttpBindingElement: StandardBindingElement
{
protected override Type BindingElementType
{
get { return typeof(PollingDuplexHttpBinding); }
}

[ConfigurationProperty("inactivityTimeoutInMinutes")]
public int InactivityTimeoutInMinutes { get; set; }

[ConfigurationProperty("serverPollTimeoutInSeconds")]
public int ServerPollTimeOutInSeconds { get; set; }

protected override void OnApplyConfiguration(System.ServiceModel.Channels.Binding binding)
{
PollingDuplexHttpBinding poll = (PollingDuplexHttpBinding)binding;
poll.InactivityTimeout = new TimeSpan(0, 0, this.InactivityTimeoutInMinutes, 0);
poll.ServerPollTimeout = new TimeSpan(0, 0, this.ServerPollTimeOutInSeconds);

}

protected override void InitializeFrom(System.ServiceModel.Channels.Binding binding)
{
base.InitializeFrom(binding);
this.ServerPollTimeOutInSeconds = (int)((PollingDuplexHttpBinding)binding).ServerPollTimeout.TotalSeconds;
this.InactivityTimeoutInMinutes = (int)((PollingDuplexHttpBinding)binding).InactivityTimeout.TotalMinutes;

}
}


Once you’ve built this class register this class using the WCF Configuration editor by clicking the Advanced tab and add a new Binding Exension element as such:

This step now allows us to choose the Silverlight PollingDuplexHttpBinding and even configure it if we want to, as such:

At this point your WCF Service is complete. You can run this service and it is available to communicate with Silverlight Duplex clients.

Building the Silverlight Client application.
To build the Client application we can use two approaches. The first approach deals with using the Callback Contract INotifyClient to receive callbacks from the service. The Second approach uses a more loosely coupled design to generically use the IReceiveChannel of the IDuplexSessionChannel interface to receive callbacks. In my sample code, I’ve chosen to use the IDuplexSessionChannel approach.

The first step in creating a client is opening a channel to the PollingDuplexHttpBinding, channel stack. To create an open channel you use the ChannelFactory.Open() method. However when working with Silverlight everything must be done in an Asynchronous design, thus you’d use the BeginOpen()… EndOpen() APM pair, as shown in the sample code below.

private string clientName = null;
SynchronizationContext _currentThreadContext = null;
IDuplexSessionChannel duplexChannel = null;
PollingDuplexHttpBinding channelStack = new PollingDuplexHttpBinding();

IChannelFactory stackFactory = null;

void frmLogin_OnRegister(object sender, LoginPopup.RegisterEventArg e)
{
clientName = e.ClientName;
_currentThreadContext = SynchronizationContext.Current;


channelStack.InactivityTimeout = TimeSpan.FromMinutes(3);

stackFactory = channelStack.BuildChannelFactory
(new BindingParameterCollection());

IAsyncResult ar = stackFactory.BeginOpen(new AsyncCallback(onChannelFactoryOpenComplete), stackFactory);

if (ar.CompletedSynchronously)
{
OpenChannelFactory(ar);
}

TimerCallback tcb = new TimerCallback(CheckForNewMessage);
UiPoller = new Timer(tcb);


}


Once the factory is open, you have a pointer to the channels in the channel stack, which at this point you can now tell the factory to create and open the channels as shown in the code below. Again keep in mind that we must use the Asynchronous pattern here as well as shown in the sample code below.


private void OpenChannelFactory(IAsyncResult ar)
{
IChannelFactory stackFactory = (IChannelFactory)ar.AsyncState;
stackFactory.EndOpen(ar);

duplexChannel = stackFactory.CreateChannel(new EndpointAddress("http://localhost:60688/Service1.svc"));

IAsyncResult duplexAr = duplexChannel.BeginOpen(new AsyncCallback(onChannelOpenComplete), duplexChannel);
if (duplexAr.CompletedSynchronously)
{
OpenChannel(duplexAr, ActionType.Register );
}
}


Once the Channels are all created and open, we have to abilitity to send and receive data from the Transport channel that sits at the bottom of the Channel Stack. Remember how the IDuplexSessionChannel is nothing more than one IInputChannel, and one IOutputChannel. Well here all we have to do is call which one we’d like, either Receive() for receiving data, or Send() for sending data, again keeping in mind that we must follow the Asynchronous programming model. This is shown in the methods below:


private void OpenChannel(IAsyncResult ar, ActionType action)
{
duplexChannel = (IDuplexSessionChannel)ar.AsyncState;
duplexChannel.EndOpen(ar);

//Now we have an open Duplex channel to send to the Duplex service
//First register the client name.
switch (action)
{
case ActionType.Register:
RegisterClient();
break;
case ActionType.UnRegister:
UnRegisterClient();
break;
case ActionType.SendMessage:
SendMessage(null);
break;
default:
break;
}

}

private void RegisterClient()
{
String sw = "" + clientName + "";
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sw));

Message msgRegister = Message.CreateMessage(duplexChannel.GetProperty(), "RegisterClient", XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(ms)));
IAsyncResult registerAr = duplexChannel.BeginSend(msgRegister, new AsyncCallback(onSendComplete), duplexChannel);
if (registerAr.CompletedSynchronously)
{
SendComplete(registerAr);
}
PollForAnotherMessage(duplexChannel);
}

private void UnRegisterClient()
{

String sw = "" + clientName + "";
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sw));

Message msgRegister = Message.CreateMessage(duplexChannel.GetProperty(), "UnRegisterClient", XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(ms)));
IAsyncResult registerAr = duplexChannel.BeginSend(msgRegister, new AsyncCallback(onSendComplete), duplexChannel);
if (registerAr.CompletedSynchronously)
{
SendComplete(registerAr);
}
PollForAnotherMessage(duplexChannel);
}

private void SendMessage(object o)
{
if (o != null) duplexChannel = (IDuplexSessionChannel)o;

String sw = "" + txtSend.Text + "";
MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sw));

Message msgRegister = Message.CreateMessage(duplexChannel.GetProperty(), "SendMessage", XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(ms)));
IAsyncResult registerAr = duplexChannel.BeginSend(msgRegister, new AsyncCallback(onSendComplete), duplexChannel);
if (registerAr.CompletedSynchronously)
{
SendComplete(registerAr);
}
PollForAnotherMessage(duplexChannel);
}


private void PollForAnotherMessage(IDuplexSessionChannel ch)
{
IAsyncResult ar = ch.BeginReceive(new AsyncCallback(onPollComplete), ch);
if (ar.CompletedSynchronously) PollComplete(ar);
}

private void PollComplete(IAsyncResult ar)
{
IDuplexSessionChannel ch = (IDuplexSessionChannel)ar.AsyncState;
Message msg = ch.EndReceive(ar);
if (msg != null)
_currentThreadContext.Post(NotifyFromServer, msg.GetBody());

}

private void NotifyFromServer(object msg)
{
string current = txtChatWindow.Text;
string newContent = msg.ToString().Replace(current, "");
txtChatWindow.Text += newContent;
}


private void SendComplete(IAsyncResult ar)
{
IDuplexSessionChannel ch = (IDuplexSessionChannel)ar.AsyncState;
ch.EndSend(ar);
_currentThreadContext.Post(RegisteredClient, "\n");
}

private void RegisteredClient(object msg)
{
txtChatWindow.Text += msg.ToString();
}

In the example code above, there are three methods that are sending data: RegisterClient, SendMessage, and UnRegisterClient all following the same pattern of the APM, and using the BeginSend(xxx) method to send data to the Service. There is only one method for receiving data: PollForAnotherMessage(xxx), which uses the BeginReceive(xxx) Asynchronous method to retrieve a message from the Duplex WCF Service.

Below is a quick view of what the client looks like, as well as a link pointing to an example application that shows exactly how to build a Push Style Notification using Silverlight and WCF Duplex bindings.




Happy Coding!!!
References:
http://ajaxian.com/archives/a-report-on-push-versus-pull
http://swerl.tudelft.nl/twiki/pub/Main/TechnicalReports/TUD-SERG-2007-016.pdf
(http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx)
http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/
http://alex.dojotoolkit.org/2006/03/comet-low-latency-data-for-the-browser/
http://blogs.msdn.com/silverlightws/archive/2008/06/10/detailed-overview-of-silverlight-2-beta-2-web-service-features.aspx
http://eugeneos.blogspot.com/2008/04/pushing-data-to-silverlight-application.html