Silverlight Playground
about Silverlight and other Amenities

SilverlightShow EcoContest

2010-01-12T23:41:48+01:00 by Andrea Boschin

SilverlightShowEcoContest The team of silverlightshow.net announced today the first eco-contest. Obviously Silverlight is the focused technology but I really love the argument of the contest. The partecipants are invited to propose an application that will spread the word about climate change. After a failed of Copenaghen summit where the biggest and powerful countries have not been able to reach an agreement about the save of our planet there is for sure the need to embrace the cause and let people to be aware of this problem.

So this post would want to connect many people with the contest and hopefully with the climate changes argument. There is a great prize that I think a Silverlight enthusiast must not miss: A MIX10 invitation with hotel and travel expenses included.

The contest will end at 15 February so there is really few time to join an propose the applications. Here is the contest website:

http://contest.silverlightshow.net/

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Writing a server-less conferencing client with Silverlight 4.0 UDP Multicast

2010-01-02T22:42:07+01:00 by Andrea Boschin

When I wrote my article about , I received many questions about writing application that communicate each other with this protocol. The reason for this request is that many people believe that Silverlight being a good platform for game developers due to its great graphical features and its simplicity, so a lot of them want to implement some kind of communication for on-line collaborative games.

Local connections have not been made for this kind of usage because them are available only for communication between application instances running in the same machine and it is not possible to use them to create gaming communications.

With Silverligth 4.0 the System.Net namespace hosts a new kind of socket communications, named UDP Multicast, that seems to be a possible solution for gaming applications but also for applications requiring fast communication between multiple clients, like conferencing applications also with video streaming support.

, also know as IP Multicast, is a well-known protocol that enables the ip infrastructure to replicate messages from multiple sources to be delivered easily to an undefined number of subscribers. The protocol works using a special class of IP addresses (224.0.0.0/4 for ipV4) where each single address represent a group of clients that is communicating each other relying on the network infrastructure for the replication of the messages. This enable the creation of client applications that do not need to have a central server where clients needs to connect using the common TCP sockets.

Like the common UDP protocol, IP Multicast is a not-connected protocol that does not guarantee the arrival of the messages and the order of delivery. So if you need a realiable channel the better is to rely on TCP sockets or you need to implement some kind of consistency check.

Writing a conferencing client

The first example I wrote to test the UDP Multicast feature is a simple conferencing client that enable people to join a multicast group and then send messages to the other members of the group.  The example you can download at the end of the article is very simplified and let the user specify an username (without checking if someone else is using the same username) and join the muklticast group. Then the user can type messages and send them to all the group members.

Silverlight 4.0 has two new classes to implement a multicast client

1) UdpSingleSourceMulticastClient let work with a single well-known source that is the unique client allowed to send to the group. This is the one-to-many communication. You can imagine to write a video source with this class and multiple clients to receive packets from it.

2) UdpAnySourceMulticastClient enables all the clients both to send and receive to or from the multicast group. This let you create something similar to a conferencing application where many-to-many connection is required.

When you use a multicast client the first thing you have to do is to join the group, using the known muticast ip address (ex: 224.0.0.1) and the port (ex: 3000). When the connection have been made you can start send and/or receive from the group. Differently from the TCP sockets with UDPMulticast you do not have a restricted set of ports to use. All the ports above of 1024 are available to the plugin.

Here is a snippet from my UDPAnySourceMulticastChannel I wrote for my example:

   1: public UdpAnySourceMulticastChannel(IPAddress address, int port, int maxMessageSize)
   2: {
   3:     this.ReceiveBuffer = new byte[maxMessageSize];
   4:     this.Client = new UdpAnySourceMulticastClient(address, port);
   5: }
   6:  
   7: public void Open()
   8: {
   9:     if (!this.IsJoined)
  10:     {
  11:         this.Client.BeginJoinGroup(
  12:             result =>
  13:             {
  14:                 this.Client.EndJoinGroup(result);
  15:                 this.IsJoined = true;
  16:                 Deployment.Current.Dispatcher.BeginInvoke(
  17:                     () =>
  18:                     {
  19:                         this.OnAfterOpen();
  20:                         this.Receive();
  21:                     });
  22:             }, null);
  23:     }
  24: }

In the constructor of the class, I've created an instance of the multicast client with the required address and port, then in the Open method I've called the BeginJoinGroup method that starts an asyncronous join request to the multicast address. As always the Silverlight's communication is asyncronous so when the callback is called I need to invoke the EndJoinGroup and then marshal the thread to the user interface with using the Dispatcher.

When the group has been joined you can start receiving and sending. This two actions are simultaneous because while you are receiving messages (or you are waiting to receive) you can also send messages to the group. So you have to invoke the BeginReceiveFromGroup method that starts listening for incoming packets and calls the callback method when something has been received. While the client is waiting for something to receive you can also call the BeginSendToGroup method to send something to the group. You have to be aware that when you send a packet to the group you will also receive the packet you sent because the multicast will replicate the message to all the joined clients.

   1: private void Receive()
   2: {
   3:     if (this.IsJoined)
   4:     {
   5:         Array.Clear(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length);
   6:  
   7:         this.Client.BeginReceiveFromGroup(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length,
   8:             result =>
   9:             {
  10:                 if (!IsDisposed)
  11:                 {
  12:                     IPEndPoint source;
  13:                     this.Client.EndReceiveFromGroup(result, out source);
  14:                     Deployment.Current.Dispatcher.BeginInvoke(
  15:                         () =>
  16:                         {
  17:                             this.OnReceive(source, this.ReceiveBuffer);
  18:                             this.Receive();
  19:                         });
  20:                 }
  21:             }, null);
  22:     }
  23: }
  24:  
  25: public void Send(string format, params object [] args)
  26: {
  27:     if (this.IsJoined)
  28:     {
  29:         byte[] data = Encoding.UTF8.GetBytes(string.Format(format,args));
  30:  
  31:         this.Client.BeginSendToGroup(data, 0, data.Length,
  32:             result =>
  33:             {
  34:                 this.Client.EndSendToGroup(result);
  35:             }, null);
  36:     }
  37: }

The UDPAnySourceMulticastClient class has some other interesting methods. You can send messages to the group specifing the destination so the network infrastructure will route the message to a single target. You can also block and unblock an IPAddress to prevent messages incoming from it to be received.

There is not a "Disconnect" or "Close" method but when you need to end the communication you can call the Dispose method of the client class. This will cause the pending receive to be dropped. It is important to have a flag set when the class is disposing because when the pending receive is dropped your callback is notified and you have to be aware that the client instance is not valid anymore and avoid to call the EndReceiveFromGroup method alse you will get an exception.

   1: /// <summary>
   2: /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
   3: /// </summary>
   4: public void Dispose()
   5: {
   6:     if (!IsDisposed)
   7:     {
   8:         this.IsDisposed = true;
   9:  
  10:         if (this.Client != null)
  11:             this.Client.Dispose();
  12:     }
  13: }

The client needs only to create an instance of the class an then call the Open method to join the multicast group. The channel then automatically starts listening from incoming packets and raise an event every time it detect something. So when the user hit the send button it I can call the Send() method to send a new packet and when the channel notify me about the arrival of a packet I add it to the logging listbox. I've added an AfterOpened and BeforeClose events to allow the client to send a message just after joining the group and before leaving it.

PolicyServer

Like other networking tools in Silverlight, the ip multicast requires something issuing a policy file. This is the sole server-side requirement for this protocol working fine. The policy server has to implement a two UDP messages system. The first message, sent by the client, is a datagram called "announcement" that asks the server to issue a policy file. When the server receive this message have to send an xml file that authorize to the client to communicate with a particular ip address and port. The mechanism is very similar to the TCP socket policy server but use an UDP messagging system.

To implement this server the best is downloading this project from MSDN code gallery. The project contains a working policy server that you can simply start from a console application or from a win32 service.

The drawbacks

The application I have included at the end of the article is very simple and demostrate the power of this messaging system, that was initially designed for effective video streaming. Unfortunately there is some drawbacks. First of all, also if I've entitled this example "server-less" this is true for the 99%. You need a policy issuer that is a little server, but it is not crucial for performance concerns. The system is really simpler than an always-connected TCP implementation and due to the nature of the UDP protocol really require less resources.

Another concern is about the security and realiability. The UDP protocol does not implements some infrastructure to avoid the ip spoofing and does not guarantee the packet delivery and the arrival order. In a real world solution you have to be aware of these limitation and take care of them. You have to write code to sign packets to know from whom they are issued and to handle packet loss and unordered delivery. This may be someway complex, but is a little price to pay for the effectiveness of this protocol.

Finally, the major drawback is that the most common firewalls manage to block this kind of traffic. If using a TCP socket server on a well known port is someway difficult due to the need of having firewall configurations, implementing a multicast is probably more complex specifically if you need to send the packets through the Internet. So in my opinion the most common scenario for this protocol to work is a local area network where you can manage to have firewalls and network infrastructure comply with it.

Download: SilverlightPlayground.UDPMulticast.zip (181 KB)

Categories:   Networking
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

A generic ViewModel to publish sets of objects

2009-12-16T22:14:18+01:00 by Andrea Boschin

The programming with the MVVM pattern often requires a proliferation of types because there are more Views that need a ViewModel than you might think. You can think that you need to associate a ViewModel only to simple blocks of your user interface, but while you are writing code you often understand that there are other cases where a ViewModel is required.

As an example while populating a DataGrid binding simple entities to the grid is not  good idea. A single row of a grid not only contains some data to be displayed but often may contain some commands, a link to be clicked, a button to delete an item and so on.

All these are cases where you need a ViewModel to correcty handle the binding and the related commands. So you have to create a new type, add a bunch of properties and some commands and finally populate the grid with instances of the new type. Then you will find someway difficult to route the command from the child ViewModel to the one that has generated it.

Simple is better.

In my recent applications I found a reasonable workaround that correctly handle the situation but avoid a proliferation of classes and as usual in this cases the solution comes from a generic type. The trick comes from the understanding that often in this scenario you have some properties of an entity to be binded and one or two commands to be raised. And in the most cases the command have to be handled by a parent ViewModel. Imagine to have a collection which is shown in a DataGrid and a delete command on each row; To remove the row, the command has to be catched by the ViewModel which is exposing the collection. So I decided to create a simple class named RowViewModel this way:

   1: public class RowViewModel<T,K> : ViewModel
   2:     where T : ViewModel
   3: {
   4:     /// <summary>
   5:     /// Initializes a new instance of the RowViewModel class.
   6:     /// </summary>
   7:     /// <param name="parent">The parent.</param>
   8:     /// <param name="payload">The payload.</param>
   9:     public RowViewModel(T parent, K payload)
  10:     {
  11:         this.Parent = parent;
  12:         this.PayLoad = payload;
  13:     }
  14:  
  15:     /// <summary>
  16:     /// Gets or sets the parent.
  17:     /// </summary>
  18:     /// <value>The parent.</value>
  19:     public T Parent
  20:     {
  21:         get { return this.GetValue<T>("Parent"); }
  22:         set { this.SetValue<T>("Parent", value); }
  23:     }
  24:  
  25:     /// <summary>
  26:     /// Gets or sets the pay load.
  27:     /// </summary>
  28:     /// <value>The pay load.</value>
  29:     public K PayLoad
  30:     {
  31:         get { return this.GetValue<K>("PayLoad"); }
  32:         set { this.SetValue<K>("PayLoad", value); }
  33:     }
  34: }

To simplify the creation of the collection property I've created a class RowViewModelCollection that inherits from the ObservableCollection. This allow me to declare the observable properties with a less verbose syntax:

   1: public class RowViewModelCollection<T, K> : ObservableCollection<RowViewModel<T, K>>
   2:     where T : ViewModel
   3: { }

Now we are ready to publish a DataGrid using this class. The RowViewModel exposes T as the parent ViewModel and K as the payload. This is the entity we want to display in the grid. So we can write a XAML similar to this:

   1: <data:DataGrid ItemsSource="{Binding Tasks}">
   2:     <data:DataGrid.Columns>
   3:         <data:DataGridTemplateColumn>
   4:             <data:DataGridTemplateColumn.CellTemplate>
   5:                 <DataTemplate>
   6:                     <HyperlinkButton cmd:Click.Command="{Binding Parent.DeleteTaskCommand}"
   7:                                      cmd:Click.CommandParameter="{Binding PayLoad}"
   8:                                      HorizontalAlignment="Center" VerticalAlignment="Center" >
   9:                         <Image Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Width="16" Source="/Elite.TimeTracker.Client;Component/Images/delete.png" Stretch="Fill"/>
  10:                     </HyperlinkButton>
  11:                 </DataTemplate>
  12:             </data:DataGridTemplateColumn.CellTemplate>
  13:         </data:DataGridTemplateColumn>
  14:         <data:DataGridTextColumn Header="Cliente" Binding="{Binding PayLoad.Customer.Description}" />
  15:         <data:DataGridTextColumn Header="Ora" Binding="{Binding PayLoad.StartTime}" />
  16:         <data:DataGridTextColumn Header="Descrizione" Binding="{Binding PayLoad.Description, Converter={StaticResource ellipsis}}" />
  17:         <data:DataGridCheckBoxColumn Header="Chiam." Binding="{Binding PayLoad.IsPhoneCall}" />
  18:         <data:DataGridCheckBoxColumn Header="Compl." Binding="{Binding PayLoad.IsCompleted}" />
  19:     </data:DataGrid.Columns>
  20: </data:DataGrid>

In a couple of words we have:

ItemsSource="{Binding Tasks}" - This connect the DataGrid to a RowViewModelCollection declared in the parent ViewModel.

Binding="{Binding PayLoad.StartTime}" - This take advantage of the dot syntax of the DataBinding that allow to access complex properties of the binded objects. Remember that PayLoad is the instance of the entity to bind to the DataGrid so PayLoad.StartTime binds the StartTime property to the cell.

cmd:Click.Command="{Binding Parent.DeleteTaskCommand}" - This binds the click event of the HyperlinkButton to a command of the parent ViewModel.

cmd:Click.CommandParameter="{Binding PayLoad}" - This binding let me pass the entire entity the delegate command.

This tecnique simplifies the code required to handle the DataGrid. When a command is raised the parent ViewModel handle it and this reduce the need to use an EventBroker, and it gives a more simple and maintainable code.

Is this good only for DataGrids?

There are a lot of cases where you have to bind a collection to a control, the ItemsControl, the ListBox, and so on. Every time you encounter one of these cases you can obviously apply this tecnique. Of course it is useful only if you need to handle some commands, otherwise you can simply bind the entity directly to the control.
In the code I've attached to a my previous post - the -you can find a working sample of the workaround. 

Categories:   Databinding | TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Silverlight 4.0 beta released

2009-11-18T18:22:15+01:00 by Andrea Boschin

Download Sample Code: SilverlightPlayground.SL4BetaTestConsole.zip (89K)

 

During the Keynote of the PDC 2009 a new beta of Silverlight has been announced and made available. I think very few people did expect the early release of the version 4.0, and if you think in terms of number of new features compared with the time passed since the RTW of Silverlight 3.0 - only four months - you understand the big work made by one of the most prolific teams of Microsoft.

In the latest month I could play with the beta bits, and I've compiled a collection of the most important features coming in this release, to understand how them works and to release some working code to let people easily learn them. This collection is linked at the end of this post in the form of a self-explaining navigation application. The application contains eleven samples that show the features I list below:

Full Trust in Out of Browser: While detaching an application to out of browser now it is possible to give full trust to the installed application. This enable huge improvements: no need of cross domain policies, access to file system, no user-initiated dialogs. You can also use COM interoperability.

WebCam: Silverlight 4.0 introduce some new API to handle video and audio capture. This sample shows how to use the CaptureSource class to detect video devices and to capture live stream and snapshots from it. The same pattern can be used to capture audio sources

WebBrowser: This new control has been added to the Silverlight bits to enable the use of html hosting into Silverlight applications. The WebBrowser control is available only when the application is running out of browser so before running the sample you need to install the application

RichTextArea: Another new control let the user enter formatted code. The RichTextArea behave like a TextBox but it can host fonts, weights, styles, and entering graphic elements and links like you can do with a text editor. The sample show also how to read the content of the RichTextArea you can populate with XAML markup.

HTML Brush: Like using a media element to publish a video on a brush with the HtmlBrush it is possible to use the output of a WebBrowser control to render the brush. The use of this feature has some limits but the code works fine.

PrintDocument: In the development of Line of Business applications, sending documents to the printer is an useful feature. Silverlight 4.0 introduce a new PrintDocument that enable sending elements of the Visual Tree to the printer.

Righ Mouse Button: In the previous releases the context menu of Silverlight prevent the use of the Right mouse button. In this release you can intercept this button and attach the logic you need. In the sample you can use left and right buttons to change the size of the circle. If you click outside the circle the normal context menu will be displayed.

DataBinding to DependencyObject: In the current version the DataBinding between elements is available only when the target inherits from FrameworkElement. This limit prevent, as an example, to bind multiple a RotateTransform to a single Slider. In Silverlight 4.0 this limit has been overcome and now it is possible to bind DependencyObjects. This is a great step in the compatibility with WPF.

Improvements to Binding: The binding markup extension has been enriched with a new set of properties which simplify the development. This include StringFormat, FallbackValue and TargetNullValue.

Commands: The controls inheriting from ButtonBase has acquired two new properties, Command and CommandParameter. It is a tiny step in the direction of MVVM programming.

Drag & Drop: With this release it is possible to detect dragging of elements on the application surface. The sample read the filename, la last access date and the size of the stream.

Notification Window: Desktop application can show a popup in the tray bar of Windows. This now is available also in Silverlight out of browser applications.

These are a huge set of features for the short period of time where they were developed. I hope many of you will find useful the code I've linked to this post. If you need help to understand the samples feel free to contact me through the contact form.

Download: SilverlightPlayground.SL4BetaTestConsole.zip (89K)

Categories:   News | Demo
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed

My Model-View-ViewModel exercise

2009-11-13T01:32:04+01:00 by Andrea Boschin

Senza-titolo-1 Some weeks ago I've worked on an exercise originally started to try writing a complete application with full Model-View-ViewModel pattern. I've created the application with Visual Studio 2008, Prism to integrate missing features and Ria Services July CTP to get access to a SQL Server 2008 Database.

The application is a little time tracker, and I've decided to attach it to this post because it was very useful to me to understand problems and missing things about the MVVM pattern.

In the next days I will write some words about these problems I found, but for now I only want to undisclose the application to let something download it and give me some comments about it.

If you decide to try the application remember to attach the database mdf in the zip file, to set the connection strings in the web.config and the credentials for reporting services if you want to setup it and finally enter "tracker" as username and p@ssw0rd as password.

I'm currently learning this pattern and I do not want to consider my implementation complete, perfect and without any error. So please let me know what do you think and how can I improve it. Thanks in advance.

Download: Elite.TimeTracker.zip (~820 Kb)

Categories:   Prism | Demo
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

How to configure an AuthenticationDomainService using Ria Services Class Library

2009-11-06T11:36:01+01:00 by Andrea Boschin

Using a Ria Services Class library to collect DomainServices and DomainContexts in a solution is a good practice because everyone know the value of having classes separated in projects instead of having them in the web project.

If you try to create this kind of project and then you add an Authentication Domain Service with the July 2009 CTP of Ria Services you will find two major drawbacks. First of all you will notice the generated code does not contains a RiaContext class. RiaContext is the class responsible to handle the User and roles and configure the type of Authentication to use in the application.

To workaround to this problem you may simply write by hand this class and put it in the client side part of the Ria Services library project. The code can be copied by an AuthenticationDomainContext generated in the web project but it is very simple and I show you the code here:

   1: public sealed partial class RiaContext : System.Windows.Ria.RiaContextBase
   2: {
   3:     #region Extensibility Method Definitions
   4:  
   5:     partial void OnCreated();
   6:  
   7:     #endregion
   8:  
   9:     public RiaContext()
  10:     {
  11:         this.OnCreated();
  12:     }
  13:  
  14:     public new static RiaContext Current
  15:     {
  16:         get
  17:         {
  18:             return ((RiaContext)(System.Windows.Ria.RiaContextBase.Current));
  19:         }
  20:     }
  21:  
  22:     public new User User
  23:     {
  24:         get
  25:         {
  26:             return ((User)(base.User));
  27:         }
  28:     }
  29: }

With this class you can configure the Authentication Domain Context as you did with the generated class. So you have to add it to the App.config, in the ApplicationLifetimeObjects tag and then add a kind of authentication like the WindowsAuthentication and FormsAuthentication.

The second drawback is that if you run the project this way and then you call the Login() method (or any other method) of the RiaContext you will get an error:

The DomainContextType is null or invalid and there are no contexts generated from AuthenticationBase<T>

This probably come from the fact that the RiaContext is not correctly initializated so when the class search for a valid domaincontext to handle the Login call it fails because it does not find it. The tip to correct this behavior is to specify the DomainContext property in the Authentication you have choosed. Here is how to change the App.xaml file:

   1: <Application.ApplicationLifetimeObjects>
   2:     <slpgria:RiaContext>
   3:         <slpgria:RiaContext.Authentication>
   4:             <appsvc:FormsAuthentication>
   5:                 <appsvc:FormsAuthentication.DomainContext>
   6:                     <slpgdc:MyAuthenticationDomainContext />
   7:                 </appsvc:FormsAuthentication.DomainContext>
   8:             </appsvc:FormsAuthentication>
   9:         </slpgria:RiaContext.Authentication>
  10:     </slpgria:RiaContext>
  11: </Application.ApplicationLifetimeObjects>

As you can see you have simply to give an instance of the generated Authentication Domain context class to the FormsAuthentication (or Windows Authentication as well). The RiaContext need to have this instance to make the calls to the BL methods in the Domain Service.

I really do not know if this behavior will be corrected in the next releases of RiaServices. The solution is pretty simple but take me some hours to understand what are going wrong. So I hope this may help you to spare some time making your experiments with the current release.

Categories:   TIPS | Networking
Actions:   E-mail | del.icio.us | Permalink | Comments (6) | Comment RSSRSS comment feed

Handling duplicated connections on Polling Duplex

2009-10-23T00:46:00+01:00 by Andrea Boschin

The last tip I would like to propose is a tecnique to avoid a single client machine connect multiple times to the same polling server. This may be the case when the user starts two or more instances of the browser or open the same page in multiple tabs. In this scenario may be unuseful to have every page connected to the server.

In Silverlight 3.0 there is a way to check when a plugin has been loaded many times. When you try to create a LocalReceiver with the same name from two instances you get an exception because they cannot share the same name. So using a LocalReceiver you can check if another browser is open.

   1: public override void Start()
   2: {
   3:     LocalMessageReceiver receiver = this.CreateReceiver();
   4:  
   5:     if (receiver != null)
   6:     {}  // receiver created: I'm the master...
   7:     else
   8:     {}  // cannot create receiver: I'm a slave...
   9: }
  10:  
  11: private LocalMessageReceiver CreateReceiver()
  12: {
  13:     try
  14:     {
  15:         LocalMessageReceiver receiver = new LocalMessageReceiver("PollingReceiver");
  16:         receiver.Listen();
  17:         return receiver;
  18:     }
  19:     catch(ListenFailedException)
  20:     {
  21:         return null;
  22:     }
  23: }

 

Checking the presence of another instance is only half of the work to do. When you detect you are a slave in the machine you need to avoid connecting - slave does nothing because a master already exists - and probably you have to change the user interface to let the user know that there is another instance running.

In my application I need to check the presence of the master every few seconds to let a slave becoming a master. To do this I've created two classes MasterPollingClientCode  SlavePollingClientCore implementing the same interface IPollingClientCore. The first class connect to the server and the other class simply does nothing.

   1: public override void Start()
   2: {
   3:     LocalMessageReceiver receiver = this.CreateReceiver();
   4:  
   5:     if (receiver != null)
   6:         this.Core = new MasterPollingClientCore(this.SessionId, this.EndPoint, receiver);
   7:     else
   8:         this.Core = new SlavePollingClientCore(this.LocalId, 
                          new LocalMessageSender("PollingSender" + this.LocalId.ToString()));
   9:  
  10:     this.Core.AlarmReceived += new EventHandler<NotifyAlarmReceivedEventArgs>(Core_AlarmReceived);
  11:     this.Core.Connected += new EventHandler(Core_Connected);
  12:     this.Core.Disconnected += new EventHandler(Core_Disconnected);
  13:     this.Core.Fault += new EventHandler<PollingFaultEventArgs>(Core_Fault);
  14:     this.Core.Start();
  15:     base.Start();
  16: }
 

The container class, then starts a thread. This thread try to create a new LocalReceiver and when it is able to get an instance it change the core class from slave to master and connect to the server. This way the client is always connected to the server with alwasy one simple connection:

   1: protected override void ThreadProc()
   2:     {
   3:         Debug.WriteLine("ThreadProc");
   4:  
   5:         while(WaitHandle.WaitTimeout == WaitHandle.WaitAny(this.ExitHandles, 5000))
   6:         {
   7:             if (this.Mode != PollingClientMode.Master)
   8:             {
   9:                 Deployment.Current.Dispatcher.BeginInvoke(
  10:                     ()=> this.TryConvertToMaster());
  11:             }
  12:         }
  13:     }
  14:  
  15:     /// <summary>
  16:     /// Tries the convert to master.
  17:     /// </summary>
  18:     private void TryConvertToMaster()
  19:     {
  20:         Debug.WriteLine("TryConvertToMaster");
  21:  
  22:         LocalMessageReceiver receiver = this.CreateReceiver();
  23:  
  24:         if (receiver != null)
  25:         {
  26:             Debug.WriteLine("created");
  27:  
  28:             // detach all
  29:             this.Core.Stop();
  30:             this.Core.AlarmReceived -= new EventHandler<NotifyAlarmReceivedEventArgs>(Core_AlarmReceived);
  31:             this.Core.Connected -= new EventHandler(Core_Connected);
  32:             this.Core.Disconnected -= new EventHandler(Core_Disconnected);
  33:             this.Core.Fault -= new EventHandler<PollingFaultEventArgs>(Core_Fault);
  34:             // create new core
  35:             this.Core = new MasterPollingClientCore(this.SessionId, this.EndPoint, receiver);
  36:             // attach all
  37:             this.Core.AlarmReceived += new EventHandler<NotifyAlarmReceivedEventArgs>(Core_AlarmReceived);
  38:             this.Core.Connected += new EventHandler(Core_Connected);
  39:             this.Core.Disconnected += new EventHandler(Core_Disconnected);
  40:             this.Core.Fault += new EventHandler<PollingFaultEventArgs>(Core_Fault);
  41:             this.Core.Start();
  42:         }
  43:     }
 
 

If you are brave you can try to implement a communication between Slave and Master using a LocalSender. Using the code I provider this task cannot be too hard.

Good Work

Categories:   Networking
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

How to avoid flooding a PollingDuplex server

2009-10-06T14:37:39+01:00 by Andrea Boschin

Returning on the PollingDuplex argument, today I would like to illustrate a tecnique I used to avoid the flooding in my Polling Duplex service. The problem come from the fact that my server retain a list of connected clients and is unable to detect the disconnection in a short time. After a while the notification from the server to the disconnected client will timeout so the server handle the timeout and remove the client from its list. But if for some reason a client Register itself multiple times the server notification list will grow and this may become a problem causing the service to slow down its response time.

In a recent project I have to address this issue because of the way the polling client works. Imagine having a instant messaging client using PollingDuplex in all the pages of a portal. When the user navigate in the website the polling client will repeatly connect and disconnect from the polling server because the user may change page after short time.

How to generate a persistent ClientID

To handle this problem I need to have a globally unique id identifing the connecting client. If the ID is unique across different connected clients the server can use this ID to search previuos instances of the client in his notification list and if found it discart the old client and replace it with the new one. The solution is pretty simple but it require the ability to generate a very unique id (obviously a Guid) and then persist it across different browser session.

The trick is to use the Isolated Storage. The first time I start the client it generate the Guid and save it in the IsolatedStorageSettings collection. Then it use the guid to connect and register to the polling server.

All the other times the client find the Guid in the IsolatedStorageSettings and avoid to generate another Guid but use the old identifier. Here is the code to generate the guid or take id from the storage:

   1: private void Application_Startup(object sender, StartupEventArgs e)
   2: {
   3:     Guid key;
   4:  
   5:     if (!IsolatedStorageSettings.ApplicationSettings.Contains("InstanceKey"))
   6:     {
   7:         key = Guid.NewGuid();
   8:         IsolatedStorageSettings.ApplicationSettings["InstanceKey"] = key;
   9:         IsolatedStorageSettings.ApplicationSettings.Save();
  10:     }
  11:     else
  12:         key = (Guid)IsolatedStorageSettings.ApplicationSettings["InstanceKey"];
  13:  
  14:     this.RootVisual = new MainPage(key.ToString());
  15: }

I put the code in the Application_Startup method then I pass the key to the MainPage constructor because it must use the guid to connect to the server.

On the server side I've slightly changed the Register method and the Polling thread to handle the new guid. First of all I request the id in the Register method:

   1: public void Register(string sessionId)
   2: {
   3:     IPollingServiceClient client =
   4:         OperationContext.Current.GetCallbackChannel<IPollingServiceClient>();
   5:  
   6:     PollingMonitor.Current.Register(client, sessionId);
   7: }

Then the server checks his notification list to add or change the callback client:

   1: /// <summary>
   2: /// Adds the specified item.
   3: /// </summary>
   4: /// <param name="item">The item.</param>
   5: public void Add(IPollingServiceClient client, string sessionId)
   6: {
   7:     var found = (from c in this
   8:                  where c.SessionId == sessionId
   9:                  select c).SingleOrDefault();
  10:  
  11:     if (found != null)
  12:         found.ChangeClient(client);
  13:     else
  14:         this.Add(new PollingClient(client, sessionId));
  15: }

The ChangeClient() method simply put the new callback client in the object instance representing the client in the list.

There are only two drawbacks in this tecnique. The first is that the user can clear his IsolatedStorage using the Silverlight context menu. This deletes the saved Guid so the next time the client connect to the server it generate another Guid. On the other side someone may discover some privacy concerns on having an id globally identifying the client because this may become a way to track the user activities. You have to be aware of this problem and eventually you can mitigate the problem using a TTL to invalidate the Guid after some hours or days so the client will change the Guid and the tracking become hardest.

Categories:   TIPS | Networking
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Handling faults on PollingDuplex while server is not available

2009-09-25T15:57:34+01:00 by Andrea Boschin

During the development of the project I'm currently working I've implemented a polling duplex client and I found some improvements to the code I've published some weeks ago in this post.

The problem I would like to answer here is caused by server unavailability that may origin in many causes. In my scenario I'm using a WCF service hosted by Internet Information Server. While I'm using a server-side thread running in the context of the Application Pool there may be some conditions where Application Pool is recycled so the server thread is aborted and the PollingDuplex communication stops.

There is many reasons why we have to avoid this condition. In my case it is important that the client continue receive updates from the polling server without it require a page refresh from the user. So I've implemented a fault handling procedure that let my client detect when the server become unavailable and then it retry connecting and restart server side thread.

First of all we have to write a registration procedure. My duplex channel work using a Register() ServiceOperation called by the client that subscribe the client in the server thread for updates notification. The client callback contract has a single NotifyAlarm() method used by the server to notify messages to client. Here is the client-side code I use to start the polling:

   1: /// <summary>
   2: /// Registers this instance.
   3: /// </summary>
   4: private void Register()
   5: {
   6:     this.Client = new PollingServiceClient(
   7:         new CustomBinding(
   8:             new PollingDuplexBindingElement
   9:                 {
  10:                     InactivityTimeout = new TimeSpan(1, 0, 0),
  11:                     ClientPollTimeout = new TimeSpan(0, 1, 0)
  12:                 },
  13:             new BinaryMessageEncodingBindingElement(),
  14:             new HttpTransportBindingElement()),
  15:         this.EndPoint);
  16:  
  17:     this.Client.NotifyAlarmReceived += 
  18:         new EventHandler<NotifyAlarmReceivedEventArgs>(Client_NotifyAlarmReceived);
  19:     this.Client.InnerChannel.Faulted += 
  20:         new EventHandler(Client_Faulted);
  21:     this.Client.RegisterCompleted += 
  22:         new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(Client_RegisterCompleted);
  23:     this.Client.RegisterAsync(this.SessionId);
  24: }

To handle channel fault I subscribe the Faulted event in the InnerChannel. I cannot find any other way to detect when the polling fail due to server unavailability. If you trace the polling of the client and then simulate the server unavailability, recycling the application pool you will see a 404 error (if you use ClientHttpStack the error will be more specific).

Untitled

When this error occur the InnerChannel.Faulted event is raised so you can restart the polling calling the Register() method again. In the Faulted event handler I simply call the Register method again. 

   1: /// <summary>
   2: /// Handles the Faulted event of the Client control.
   3: /// </summary>
   4: /// <param name="sender">The source of the event.</param>
   5: /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
   6: void Client_Faulted(object sender, EventArgs e)
   7: {
   8:     Deployment.Current.Dispatcher.BeginInvoke(
   9:         () =>
  10:         {
  11:             this.OnDisconnected();
  12:             this.Register();
  13:         });
  14: }

The better will be starting a Timer to retry connection on a regular timeout to let the client returning online after longer server unavailability. This may be useful also when we start the polling because we can dowload the Silverlight application from a server but then it starts the polling to another server. So I've added some code in the RegisterCompleted event handler and when I get an exception from the Register() method I start a separate thread. It waits for 60 seconds then recall the Register() method again.

   1: void Client_RegisterCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
   2: {
   3:     if (e.Error == null)
   4:         this.OnConnected();
   5:     else
   6:     {
   7:         this.OnFault(e.Error);
   8:  
   9:         ThreadPool.QueueUserWorkItem(
  10:             (o) =>
  11:             {
  12:                 Thread.Sleep(60000);
  13:  
  14:                 Deployment.Current.Dispatcher.BeginInvoke(
  15:                     () => this.Register());
  16:             });
  17:     }
  18: }

You have to be aware that the Faulted event require you to marshal the context of the thread before updating any UI element. In my code I raise an event of a wrapper object to let UI reflect the temporary disconnection. So I have to use the Dispatcher to marshal the Thread to the UI.

This is all for now. I will write more on this argumet on the next days to handle a different condition.

Categories:   Networking
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

A Prism (Unity) Service to create Views

2009-08-31T21:10:03+01:00 by Andrea Boschin

After a long summer pause I’m back with this new post. This time I want to investigate an aspect of the Model-View-ViewModel pattern programming with Silverlight. During the summer I've started working on an application where I used Prism to implement MVVM and I found useful to write some code to easily create instance of views during application inizialization and during its lifetime. I really do not know if this is the better solution but I found it easy and useful so I've decided to share it with you. Let me say in this post I assume you are already aware of the reasons and benefits coming from the usage of the popular Model-View-ViewModel pattern and how the pattern works. I also assume you have a minimal knowledge of the Prism toolkit and Unity.

The relationship between the View and the ViewModel

In this section I would like to depict how the View and ViewModel collaborate and what we have to do to create an instance of a View and of its own ViewModel at the sole purpose of preparing the field for explaining my solution.

In the MVVM pattern the View represent the user interface and the ViewModel represent the business logic required to drive the informations displayed on the View. This way, every time we have to create a View we also have to create a specific ViewModel exposing the expected informations to be displayed. The ViewModel is not aware of the View, so It does not know how its properties are consumed, but it simply publish some data through some properties and the View will attach these properties using DataBinding.

What I've said reveal almost two things. The first is that the View does not know how the ViewModel works internally, but it have to know the structure of its surface. In other words the ViewModel have to implement a given well-known "interface" to let the View working fine. This interface contains only properties the View is expected to attach. This implementation is not truly required by the pattern but we can think it is near to reality.

The other thing we have to know is that to let the view binding to the ViewModel, we have to put the ViewModel in the DataContext of the View. So, the creation of the View involve the creation of a specific ViewModel -possibly implementing a given interface - and the assignment of this instance to the DataContext property of the View. Translating this concept in code we have to write something like this:

   1: MyView view = new MyView() 
   2: { 
   3:     DataContext = new MyViewModel() 
   4: }; 


In my projects I do not like to write this code because it does not let me impose to the ViewModel an interface implementation. I can obviously implement the interface but there is nothing checking that this implementation has been done. To avoid this problem I've decided to create a service I use every time I need to create a View. The service is responsible to check that the ViewModel implements a specific interface. So the creation of a View become this:

   1: // assuming "vbs" is an instance of the service 
   2: MyView view = vbs.CreateView<MyView>(); 

What is a service?

Before entering the service implementation details, I would like to explain what is a Service. As I've already said in the previous paragraphs I'm using , a.k.a . Prism is a collection of useful tools to let the developer apply easily the most common architectural patterns. For the purpose of this article we will use , a dependency injection container recently ported to Silverlight from the Microsoft Pattern and Practice team. It is available inside the Prism collection.

Unity is an "" container. It let you create and register instances of classes - giving them a lifetime manager responsible of how and when the class is created and destroyed - and then locate these classes when you need to use them. Creating a class and registering it in the IOC container let you having something similar to a service, always available and discoverable, you may dedicate to specific responsibility.

The purpose of Unity is to promote layer decoupling to enable unit testing of the applications, but this is out of the scope of this article. If you would like to read something about this argument please refer to the Unity home page on codeplex: http://www.codeplex.com/unity.

Anatomy of the ViewBuilderService

Now that I have briefly explained how a service works it is time to explain the basis of my ViewBuilderService. The trick is that the View have to declare somewhere the interface it expects the ViewModel to implement. We may have an interface "IMyViewModel" and a view "MyView" that can consume a ViewModel implementing this interface. Using a simple custom attribute we can decorate the View codebehind with the interface:

   1: [ViewModel(typeof(IMyViewModel))]
   2: public partial class MyView : UserControl
   3: {
   4:     public MyView()
   5:     {
   6:     }
   7: }

Declaring a custom Attribute is simple and it enable the ViewBuilderService to discover the interface to search for in the IOC container. In the next box there is the declaration of the ViewModelAttribute where I use the AttributeUsage attribute to inform the compiler where it have to expect the attribute to be applied.

   1: [AttributeUsage(AttributeTargets.Class)]
   2: public class ViewModelAttribute : Attribute
   3: {
   4:     public Type ViewModelType { get; set; }
   5:  
   6:     public ViewModelAttribute(Type viewModelType)
   7:     {
   8:         this.ViewModelType = viewModelType;
   9:     }
  10: }

To connect a ViewModel to its own interface we need to create the ViewModel and register it into the IOC container. This way the ViewBuilderService can read the ViewModelAttribute on the View and ask the container to resolve the interface and give us the ViewModel instance to put in the DataContext. The best place to register the ViewModels is a Module we have declared in the Unity Bootstrapper. In the sample attached to this article I've omitted to use a Module for the purpose of not complicate the sample. So the ViewModels are registered in the Bootstrapper itself.

   1: /// <summary>
   2: /// Registers the types.
   3: /// </summary>
   4: private void RegisterTypes()
   5: {
   6:     this.Container.RegisterType<IMyViewModel, MyViewModel>();
   7: }

Now all is ready and we can create the service. We have to remember that the service has to be registered in the IOC contained to be discoverable using the ServiceLocator. So we start creating a class that implements an interface IViewBuilderService:

   1: public class ViewBuilderService : IViewBuilderService
   2: {
   3:     private static IUnityContainer TheContainer { get; set; }
   4:  
   5:     public ViewBuilderService (IUnityContainer theContainer)
   6:     {
   7:         this.TheContainer = theContainer;
   8:     }
   9: }

The IViewBuilderService interface have to expose only a CreateView<T>() method we will implement in the service. This method is responsible of finding the ViewModel in the container, creating the View we specified in the T parameter and finally connect view and viewmodel together.

   1: public T CreateView<T>()
   2:     where T : UserControl, new()
   3: {
   4:     ViewModel vm = this.GetViewModel(typeof(T));
   5:     return new T() { DataContext = vm };
   6: }
   7:  
   8: private ViewModel GetViewModel(Type viewType)
   9: {
  10:     ViewModelAttribute attribute = 
  11:         viewType
  12:             .GetCustomAttributes(typeof(ViewModelAttribute), true)
  13:             .OfType<ViewModelAttribute>()
  14:             .SingleOrDefault();
  15:  
  16:     if (attribute == null)
  17:         throw new InvalidOperationException("Missing ViewModelAttribute");
  18:  
  19:     ViewModel vm = this.TheContainer.Resolve(attribute.ViewModelType) as ViewModel;
  20:  
  21:     if (vm == null)
  22:         throw new InvalidOperationException("Cannot Resolve ViewModel");
  23:  
  24:     return vm;
  25: }

Using the ViewBuilderService

It is time to use the service inside our applications. First of all we have to register the service into the IOC container. We can register the service like we already have registered the ViewModel using the RegisterType method. While we can use the same instance of the service in all the application we can use a ContainerControlledLifetimeManager. This type of lifetime manager will transform the service in a singleton instance.

   1: /// <summary>
   2: /// Registers the types.
   3: /// </summary>
   4: private void RegisterTypes()
   5: {
   6:     this.Container.RegisterType<IViewBuilderService, ViewBuilder>(
   7:         new ContainerControlledLifetimeManager());
   8:  
   9:     this.Container.RegisterType<IMyViewModel, MyViewModel>();
  10: }

Then now using the ServiceLocator we can discover the service when we need to create a View. The ServiceLocator is a Singleton class, that is capable to search registered types by its interface and return an instance. You can use the ServiceLocator everywhere you need to find the IViewBuilderService.  Here is the code to create a View and assign to the Shell:

   1: Grid grid = this.Shell.FindName("LayoutRoot") as Grid;
   2:  
   3: if (grid != null)
   4: {
   5:     IViewBuilderService vbs =
   6:         ServiceLocator.Current.GetInstance<IViewBuilderService>();
   7:  
   8:     MyView view = vbs.CreateView<MyView>();
   9:  
  10:     grid.Children.Add(view);
  11: }

Obviously I could use the RegionManager to put the new View into the user interface but I wanted to keep the example simple.

All the code I've tryied to explain in this post is attached at the end of the article. I hope you will find it useful in your applications and I will expect comments from you to improve my design and know your opinion about it.

Download: SilverlightPlayground.ViewBuilderService.zip (~430 kb)

Categories:   Prism | TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed

Use CollectionViewSource effectively in MVVM applications

2009-07-18T23:13:15+01:00 by Andrea Boschin

In a my I've outlined the new CollectionViewSource introduced in silverlight with the latest release. This control is really useful while we need to sort and filter collection of objects in memory, but if we need to use a Model-View-ViewModel pattern to develop our application there is some problems using the control.

To implement the MVVM pattern we need to inject a ViewModel into the View using the DataContext property. This is usual in this kind of application because we need to bind the properties of the ViewModel to the controls in the View. So if we need to use a CollectionViewSource we can try to bind a collection from the ViewModel to the CVS and then bind the control to the CVS itself. Unfortunately this approach does not work because we cannot bind the CVS directly to the DataContext of the page. Trying to do this operation we will get a AG_E_BAD_PROPERTY_VALUE exception because the control does not inherits from FrameworkElement so it does not support DataBinding.

However, if it were possible, the CollectionViewSource would force us to put a lot of code in the codebehind to handle the Filter event and the sorting property. So, we have to follow another way to use the CollectionViewSource effectively with this kind of applications.

How to use the CollectionViewSource

The only way to use the CollectionViewSource with the MVVP pattern is to expose it as the type of the bindable property. This way we can manage the properties of the CVS and handle the Filter event from inside the ViewModel without putting anything in the codebehind of the View.

First of all we have to create two properties in the ViewModel. The first property will be the ObservableCollection<T> and we will populate it with the data to display. This property can be private because it will be used only to feed the ColectionViewSource of the second property. Here is how to initialize the properties:

   1: /// <summary>
   2: /// Gets or sets the names.
   3: /// </summary>
   4: /// <value>The names.</value>
   5: public CollectionViewSource Names { get; set; }
   6:  
   7: /// <summary>
   8: /// Gets or sets the names internal.
   9: /// </summary>
  10: /// <value>The names internal.</value>
  11: private ObservableCollection<string> NamesInternal { get; set; }
  12:  
  13: /// <summary>
  14: /// Initializes a new instance of the <see cref="MainPageViewModel"/> class.
  15: /// </summary>
  16: public MainPageViewModel()
  17: {
  18:     this.NamesInternal = new ObservableCollection<string>();
  19:     this.Names = new CollectionViewSource();
  20:     this.Names.Source = this.NamesInternal;
  21:  
  22:     // populate the ObservableCollection
  23:     foreach (string item in DataSource.GetNames())
  24:         this.NamesInternal.Add(item);
  25: }

Now, to bind the CollectionViewSource in the XAML we have to rely on his View property. If we put a reference to the CVS in the property ItemsSource in the XAML it simply will not work. Here is how to correctly bind:

   1: <ListBox ItemsSource="{Binding Names.View}" Margin="5,5,5,1" Grid.ColumnSpan="4" />

Once we have connected the CVS to the collection and the UI to the CVS we can handle the commands from the View and interact with the CVS to modify how to display the data. In the sample I have a togglebutton that is raising a ChangeSortDirectionCommand. I use the DelegateCommand<T> from Prism V2.0 and when someone send the command I change the SortDescriptor in the CollectionViewSource.

In the same View the TextChanged event is raised when the user type in the textbox. This command handled by the ViewModel let the CVS refresh itself. This way the Filter event will be evaluated again and the View will be updated with the filter applied.

I've attached to the post a new version of the sample I've proposed with the first article. Now the sample use the MVVM pattern with the CollectionViewSource.

Download: Elite.Silverlight3.CollectionViewMVVM.zip (~520 KB)

Categories:   Databinding | Prism
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

Silverlight 3.0 RTW: A new HTTP stack ready for REST

2009-07-10T17:45:00+01:00 by Andrea Boschin

The paradigm behind REST services is very fascinating while it allow to manipulate resources over the network relying to Uri and Http Methods. For a few of you that are not aware of what REST means I suggest to think at the web because it is the more REST thing you know. When you are pointing your browser to a "resource" on the Internet, for example a product in a ecommerce website, you will write an Url in the browser that univocally identify the product. You now can imagine to use Http Methods to operate on this resource: the GET verb will retrieve information about it, the PUT updates the resource, the POST creates it and finally the DELETE remove the resource from the web. In a few words these are REST operations and is very cool to be able to use this paradigm to access resources from a Database. ADO.NET Data Services is born to implement this paradigm into the .NET Framework 3.5 SP1, and many libraries has been build to support different technologies, Windows Forms, WPF, ASP.NET. And obviously Silverlight 2.0 come with an implementation of a Data Service client to operate with REST resources but it is not really RESTful as you may believe the first time you use it.

The problem with Silverlight 2.0, due to limitations to the http stack coming from the use of the Browser API, is that it cannot handle all the required http methods but only the GET and POST verbs. So to workaround this limitation the Data Service library simply use POST to send PUT and DELETE operations. This workaround violate the REST paradigm and it imply you are not able to use 3rd party REST resources.

What I've briefly explained in the previous paragraphs is the main reason we really need a new http stack to overcome this limitations and to be able to implement a full REST interface. This is not the only benefit we can give for the addition of new verbs: let think for example to a new way to upload files to the server, using the PUT method.

The latest release of Silverlight 3.0 got new features going in the direction I've just explained. In the next paragraphs I will explain how to use them by exploring the pretty new http Stack, called ClientHttp.

BrowserHttpStack vs ClientHttpStack

First of all we need to know that the new http stack is completely separated from the old stack. This is an important note while we are sure the old stack remain unaltered and our applications relaying on it continue to work without any change. All the working things we already know continue to work over this stack and does not use the new one.

The ClientHttpStack in opposite to the BrowserHttpStack (these are the official names of the two actors) can be created using a static class called WebRequestCreator. This class can create instances of HttpWebRequest for both the browser and the client stack. Here is a sample showing the usage of the class.

   1: // create an instance of the Client stack
   2: HttpWebRequest rq = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(uri);
   3:  
   4: ...or...
   5:  
   6: // create an instance of the Browser stack
   7: HttpWebRequest rq = (HttpWebRequest)WebRequestCreator.BrowserHttp.Create(uri);

The HttpWebRequest created by this call is exactly the same we have used since Silverlight 2.0 so it can easily replace the browser stack in every existing application with a few line of code. We can immediately test the new stack assigning the Method property with the "PUT" value:

rq.Method = "PUT";

As we expect while the old stack thrown a "method not supported" exception, the new stack accept this assignment. Not all the http methods are allowed. Using TRACE, TRACK or CONNECT raise an error probably for security reasons. We will go deep inside some of the available methods in the next paragraph.

But this is only the most evident difference. Watching for the properties of the HttpWebRequest we will find a CookieContainer. It let us manage the cookies of the request. The old stack rely on cookies issued by the browser and it shares them with the browser itself. In the new stack we have full control of issued cookies; we can access cookies sent by the server or create our own cookies and send them. The drawback is that we cannot share cookies between client stack and browser stack but only rely on automatic management of server cookies from the client stack to allow forms authentication scenarios.

The next sample show how to use the CookieContainer to send our cookies:

   1: HttpWebRequest rq = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(uri);
   2: rq.Method = "GET";
   3: rq.CookieContainer = new CookieContainer();
   4: rq.CookieContainer.Add(
   5:     uri, new Cookie("Author", "Andrea Boschin"));

Another great news, many people will really appreciate, is that the new stack is capable of retrieving status codes from the http response. One of the most common problems with Silverlight 2.0, especially the first time someone try to use the HttpWebRequest is the unability to get errors from the server. This is because the browser do not send all status codes to the plugins but only 404 (Not Found) and 200 (OK). The forum is filled of disoriented people not understanding why they get a 404 from the server while they are calling an existing uri and the most common suggestion is to use fiddler to search the error in the traced call.

To read status codes from the response we have to catch the WebException and then get the HttpWebResponse from the exception. This may seems a bit strange but is really simple. Here is the code:

   1: rq.BeginGetResponse(
   2:     r =>
   3:     {
   4:         try
   5:         {
   6:             WebResponse rs = rq.EndGetResponse(r);
   7:             // do something with response...
   8:         }
   9:         catch (WebException ex)
  10:         {
  11:             HttpWebResponse rs = (HttpWebResponse)ex.Response;
  12:  
  13:             MessageBox.Show(
  14:                 string.Format("Webserver returned status code {0}: '{1}'", 
  15:                     (int)rs.StatusCode, 
  16:                     rs.StatusDescription));
  17:         }
  18:     }, rq);

These features is really useful but they are not used from existing classes. WCF and WebClient can only use the classic http stack. To have access to the ClientHttpStack we have to use the HttpWebRequest and dealing with problems like thread syncronization that are solved by the WebClient. But the new stack is very important and now it is time to have some samples about usage of the http methods.

GET, POST, PUT & DELETE

In the sample solution attached at the end of this article I've enclosed a sort of file system browser application. It use the new http stack to make calls to the server and retrieve xml containing the response. This kind of application was possible also with Silverlight 2.0 but to explaing usage of http methods I've used them to mimic some filesystem operations. GET will list the content of a folder, PUT upload a file or create a directory, POST is used to send credentials and finally DELETE remove files and directories.

Doing an http call is very similar to using the previous stack. We need to create an instance of the stack, set the method we want to use and then create a request as the server will expect it. The following sample make a call to get the directory content. I've splitted the operations in two methods, one doing the raw http call and the other using this low-level method create the request and parse the result. This is the low-level DoGet() method:

   1: private static void DoGet(Uri uri, Action<Stream> success, Action<Exception> fail)
   2: {
   3:     try
   4:     {
   5:         HttpWebRequest rq = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(uri);
   6:         rq.Method = "GET";
   7:         rq.CookieContainer = new CookieContainer();
   8:         rq.BeginGetResponse(
   9:             new AsyncCallback(
  10:                 r =>
  11:                 {
  12:                     try
  13:                     {
  14:                         WebResponse rs = rq.EndGetResponse(r);
  15:                         success(rs.GetResponseStream());
  16:                     }
  17:                     catch (WebException ex)
  18:                     {
  19:                         fail(CreateFailFromWebException(ex));
  20:                     }
  21:                 }), null);
  22:     }
  23:     catch (Exception ex)
  24:     {
  25:         fail(ex);
  26:     }
  27: }

The code in this listing shows the usual way to place an http call. First of all the DoGet method require I specify two callback methods to be called when the request will succeed or fail. This pattern helps to simplify the code to write avoiding handling multiple event handler. Using lambda expressions the code become very compact.

After the creation of the client stack I initialize the "Method" property with the GET verb, then I create an instance of a CookieContainer to allow the request to handle cookies. Finally calling BeginGetResponse place the call to the specified uri. When this method is called a new thread is created; In my case the body of the inner lambda expression contains the code executed in the thread. It call the EndGetResponse method (this trigger the call to the webserver) and finally ask for the Stream containing the body of the response.

As I explain in the previous paragraph I have to catch the WebException to read http status codes and translate it to an call to the fail() callback. You have to be aware that the two try-catch blocks are executed in different threads so the external block is unable to catch exception coming from the body of the lambda expression. This is the reason for having two separated blocks calling the fail method. Now watch to the following code:

   1: public static void GetDirectory(string path, Action<FileSystemItem[]> success, Action<Exception> fail)
   2: {
   3:    Uri uri = new Uri(
   4:        DataSource.ServiceUri +
   5:        "?action=directory" +
   6:        "&path=" + HttpUtility.UrlEncode(path));
   7:  
   8:    DataSource.DoGet(uri,
   9:        r =>
  10:        {
  11:            try
  12:            {
  13:                XDocument document = XDocument.Load(r);
  14:                IEnumerable<FileSystemItem> directories = DataSource.DeserializeItems(document);
  15:                Deployment.Current.Dispatcher.BeginInvoke(() => success(directories.ToArray()));
  16:            }
  17:            catch (Exception ex)
  18:            {
  19:                Deployment.Current.Dispatcher.BeginInvoke(() => fail(ex));
  20:            }
  21:        },
  22:        e => Deployment.Current.Dispatcher.BeginInvoke(() => fail(e)));
  23: }

This is the high-level method to get the directory content.  It use the same asyncronous pattern but maps the calls to the callback methods to the UI thread using an instance of the Dispatcher. While the HttpWebRequest make the calls in a different thread we need to marshal the context of the call to avoid cross-thread exception when we try to reach some UI components.

Using PUT to upload a file

Showing all the methods one-by-one is too much long. But there are another (last)  method I want to show. It is the PUT method we can use to upload files to a webserver in an alternate (and most simple) way to the use of the POST method. While the POST method require encoding the resource to base64 and forge a complex request, the PUT method simply ask to enqueue the full binary content. Here is the client code:

   1: private static void DoPut(Uri uri, FileStream file, Action<Stream> success, Action<Exception> fail)
   2: {
   3:     try
   4:     {
   5:         HttpWebRequest rq = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(uri);
   6:         rq.Method = "PUT";
   7:         rq.CookieContainer = DataSource.Cookies;
   8:         rq.BeginGetRequestStream(
   9:             new AsyncCallback(
  10:                 result => DataSource.DoPutUpload(result, file, success, fail)), rq);
  11:     }
  12:     catch (Exception ex)
  13:     {
  14:         fail(ex);
  15:     }
  16: }
  17:  
  18: private static void DoPutUpload(IAsyncResult result, FileStream file, Action<Stream> success, Action<Exception> fail)
  19: {
  20:     HttpWebRequest rq = (HttpWebRequest)result.AsyncState;
  21:  
  22:     using (Stream stream = rq.EndGetRequestStream(result))
  23:     {
  24:         int read = 0;
  25:         byte[] buffer = new byte[1024];
  26:  
  27:         while ((read = file.Read(buffer, 0, buffer.Length)) > 0)
  28:             stream.Write(buffer, 0, read);
  29:     }
  30:  
  31:     rq.BeginGetResponse(
  32:         r =>
  33:         {
  34:             try
  35:             {
  36:                 WebResponse rs = rq.EndGetResponse(r);
  37:                 success(rs.GetResponseStream());
  38:             }
  39:             catch (WebException ex)
  40:             {
  41:                 fail(CreateFailFromWebException(ex));
  42:             }
  43:         }, rq);
  44: }

The first method (DoPut) is very close to the previous method I described. The core of the upload is the DoPutUpload. It open a stream in the HttpWebRequest and write the entire content of the file to upload just before calling the EndGetRequest. When this call is made the file is send on the network to the webserver. I use an httphandler and when the PUT is receives read from the InputStream the file I write to the filesystem.

   1: private void ProcessFileRequest(string path)
   2: {
   3:     this.EvaluateIsValidUser();
   4:  
   5:     if (File.Exists(path))
   6:         throw new Exception("File already exists");
   7:  
   8:     using (FileStream stream = File.OpenWrite(path))
   9:     {
  10:         byte[] data = new byte[1024];
  11:         int read = 0;
  12:  
  13:         while ((read = this.Context.Request.InputStream.Read(data, 0, 1024)) > 0)
  14:             stream.Write(data, 0, read);
  15:     }
  16:  
  17:     this.WriteOk();
  18: }

The last code runs on the server. It receive the path of the file to write and create it in the file system. The final WriteOk() method show I can write something on the response to notify the client it have successful uploaded the file.

Some final words

The main benefit coming with the introduction of the new stack is the opportunity to be able to get access to rest resources on the internet. This is the reason for the creation of this stack someone can consider a duplication on something already exists. But the presence of new methods, the cabapility to better handle server status codes and cookies give to Silverlight 3.0 a new resource to implement great applications.

The code I attached to this article show a full implementation of all the http methods I've talk about. You have only to change the server path where the filesystem has to be explored. You can achive this by changing the BaseFolder property in the HttpRequestManager class.

Download: Elite.Silverlight3.ClientHttpStack.zip (2,1 MB)

Video: ClientHTTPStack.wmv (10,1 MB)

Categories:   Networking | News
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed