CHAPTER 6 ■ AZURE .NET SERVICES—SERVICE BUS 188 status is initially set to relay binding and will be automatically switched to direct binding a few seconds after the connection has been established. Listing 6-8. Implementation of Console Application Instantiates a Connection Starting with Relay Service using System; using System.ServiceModel; using Microsoft.ServiceBus; using System.Text; using System.Configuration; namespace SoftnetSolutions.RelayService.PublishChannel { using SoftnetSolutions.RelayService.ServiceContract; class Program { static void Main(string[] args) { PublishEventService service = new PublishEventService(); string endpoint = "RelayEndpoint"; HybridPublishService hybridPublishService = new HybridPublishService(endpoint); Console.WriteLine( string.Format( " Relay connection has been established {0}", Environment.NewLine ) ); IHybridConnectionStatus hybridConnectionStatus = hybridPublishService.ClientChannel.GetProperty<IHybridConnectionStatus>(); hybridConnectionStatus.ConnectionStateChanged += new EventHandler<HybridConnectionStateChangedArgs>( hybridConnectionStatus ConnectionStateChanged ); Console.WriteLine( string.Format(" Press <Enter> to exit publishing {0}", Environment.NewLine)); string input = Console.ReadLine(); while (input != String.Empty) { PostData postData = new PostData(); postData.Message = string.Format("[{0}]:{1}", DateTime.Now.ToString(), input); (hybridPublishService.ClientChannel as IPublishEventService) .PostMessage(postData); CHAPTER 6 ■ AZURE .NET SERVICES—SERVICE BUS 189 input = Console.ReadLine(); } hybridPublishService.ClientChannel.Dispose(); } static private void hybridConnectionStatus ConnectionStateChanged( object sender, HybridConnectionStateChangedArgs args) { Console.WriteLine( string.Format( " Connection has been switched from relay to direct connection {0}", Environment.NewLine ) ); } } } The screenshot of Figure 6-7 caught at the breakpoint from Visual Studio shows that the connection type is relayed when the connection is established. Figure 6-8 shows that the connection has been automatically switched to direct a few seconds later and that a notification event has been raised and caught by the console application. Figure 6-7. When the connection has been established the type of connection is relayed CHAPTER 6 ■ AZURE .NET SERVICES—SERVICE BUS 190 Figure 6-8. The relay service switches the connection from relayed to direct a few seconds later Test results of the exercise are shown in Figure 6-9, which demonstrates how a connection switches from relayed to direct and the messages are delivered from publisher to listener. Figure 6-9. Runtime screenshots from the results of Exercise 6-2 CHAPTER 6 ■ AZURE .NET SERVICES—SERVICE BUS 191 Using .NET Service Bus to Build a Distributed Connected Windows Application The building blocks we built in the last exercise can be used to build a direct connected Windows application system leveraging the .NET Service Bus. As Figure 6-10 shows, this system contains two Windows applications. The Draw Shape application draws shapes using random colors, sizes, and positions. The Shape Controller application picks the types of shape to draw and sends a notification to the Draw Shape application via a .NET TCP connection using WCF services. The binding mode is also the Hybrid type. The communication is initialized using the .NET Service Bus relay connection and automatically switches to direct bindings. ■ Note The code for this example is in the Exercise 6-3 bundle from the code download. Figure 6-10. Distributed direct-connected Windows application system CHAPTER 6 ■ AZURE .NET SERVICES—SERVICE BUS 192 The entire solution contains five C# projects. • Two projects, SoftnetSolutions.IShape and SoftnetSolutions.Shape, are used to handle the shape drawing. • SoftnetSolutions.RelayService.ServiceContract defines a WCF service contact. • The final two projects, SoftnetSolutions.RelayService.ShapeController and SoftnetSolutions.Shape.Draw, are Windows client-server applications. SoftnetSolutions.IShape This project defines an IShape interface, which contains one read-only property Map and one method Draw() as Listing 6-9 shows. All classes used to handle the shape drawing implement this interface. Listing 6-9. Interface Definition for IShape using System; using System.Drawing; namespace SoftnetSolutions.Shape { public enum SHAPE TYPE { CIRCLE, ELLIPSE, SQUARE, RECTANGLE, NOT SUPPORTED TYPE }; public interface IShape { void Draw(); Bitmap Map{ get; } } } SoftnetSolutions.Shape The implementation for base class Shape is shown in Listing 6-10. The constructor for this class accepts one parameter with type of windows Panel, which is used as the shape-drawing surface. The base class implements shared methods for all derived subclasses, such as those that generate random color and drawing sizes. Listing 6-10. Implementation for Base Class Shape using System; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; namespace SoftnetSolutions.Shape { abstract public class Shape : IShape { . Service Bus to Build a Distributed Connected Windows Application The building blocks we built in the last exercise can be used to build a direct connected Windows application system leveraging the. application system leveraging the .NET Service Bus. As Figure 6-10 shows, this system contains two Windows applications. The Draw Shape application draws shapes using random colors, sizes, and positions in the Exercise 6-3 bundle from the code download. Figure 6-10. Distributed direct-connected Windows application system CHAPTER 6 ■ AZURE .NET SERVICES—SERVICE BUS 192 The entire solution