Click here to Skip to main content
Click here to Skip to main content
Go to top

Windows Phone 7: How to Communicate with a Desktop Application

, 28 Mar 2011
Rate this:
Please Sign up or sign in to vote.
A simple example showing how to implement communication from a Windows Phone 7 to a standalone .NET application using HTTP.

Summary

This is a simple example showing how to implement communication from Windows Phone 7 to a standalone .NET application using HTTP.

Introduction

The example below implements a simple .NET application as a service and Windows Phone 7 application as a client. The service calculates two numbers and returns the result. The Windows Phone 7 client then uses the service to perform the calculation and displays the result.

It is typical for a cell-phone that the network connection does not have to be stable. The signal can get weak or can be temporarily lost. A good application should be able to handle this situation and should not stop working.

The example below uses the Eneter Messaging Framework that allows to setup the communication that detects disconnections, automatically tries to reconnect, and meanwhile stores sent messages in the buffer. Then, when the connection is available again, the messages stored in the buffer are sent to the receiver.

(The framework is free and can be downloaded from http://www.eneter.net. The online help for developers can be found at http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html.)

Service Application

The service .NET application is responsible for the calculation of two numbers and for the responding of results. The whole implementation is very simple. Please notice, to run the HTTP listening application, you must execute it under sufficient user rights. Otherwise the application will run, but will not listen. (The framework logs the Access Denied error on the debug port.) For debugging purposes, I recommend to execute it under administrator rights.

using System;
using Eneter.Messaging.DataProcessing.Serializing;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.Composites;
using Eneter.Messaging.MessagingSystems.HttpMessagingSystem;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;

namespace CalculatorService
{
    // The message transferring numbers to be calculated.
    public class RequestMsg
    {
        public int Number1;
        public int Number2;
    }

    class Program
    {
        // Receiver receiving requests to calculate two numbers and responding the result.
        static private IDuplexTypedMessageReceiver<int, RequestMsg> myReceiver;

        static void Main(string[] args)
        {
            // Create Http messaging.
            IMessagingSystemFactory anUnderlyingMessaging = new HttpMessagingSystemFactory();

            // The network can be unstable. Therefore, let's use
            // the buffered messaging monitoring the connection
            // and with automatic reconnect in case of the disconnection.
            // If the client does not ping longer than 5 seconds,
            // the client is considered to be disconnected
            // and its response messages are stored in the buffer.
            // If the connection occurs within 15 seconds,
            // the response messages are sent to the client.
            IMessagingSystemFactory aBufferedMessaging = 
                new BufferedMonitoredMessagingFactory(
                anUnderlyingMessaging,
                new XmlStringSerializer(),
                // maximum time, the client can be offline
                TimeSpan.FromMilliseconds(15000),
                // 'ping' frequency - this is not applicable for the receiver
                TimeSpan.FromMilliseconds(500),
                // maximum time, the 'ping' message does not have to be received
                TimeSpan.FromMilliseconds(5000)
                );


            IDuplexInputChannel anInputChannel = 
              aBufferedMessaging.CreateDuplexInputChannel(
              "http://127.0.0.1:8034/Calculator/");

            // Create message receiver - response sender.
            IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
            myReceiver = aSenderFactory.CreateDuplexTypedMessageReceiver<int, RequestMsg>();
            myReceiver.MessageReceived += OnMessageReceived;

            Console.WriteLine("Calculator service is listening to Http. " + 
                              "Press enter to stop listening ...");

            // Attach the duplex input channel and start listening
            // on the specified address.
            myReceiver.AttachDuplexInputChannel(anInputChannel);

            Console.ReadLine();

            myReceiver.DetachDuplexInputChannel();
        }

        // The method is called when a request is received.
        static private void OnMessageReceived(object sender, 
               TypedRequestReceivedEventArgs<RequestMsg> e)
        {
            // Calculate incoming 2 numbers.
            if (e.ReceivingError == null)
            {
                int aResult = e.RequestMessage.Number1 + e.RequestMessage.Number2;

                Console.WriteLine("{0} + {1} = {2}", 
                  e.RequestMessage.Number1, e.RequestMessage.Number2, aResult);

                // Send the result back.
                myReceiver.SendResponseMessage(e.ResponseReceiverId, aResult);
            }
        }
    }
}

Client Application

The Windows Phone 7 client application sends requests to calculate two numbers and displays results. If the connection is lost, the messages are buffered and the messaging system tries to automatically reconnect. Then, if reconnected, the messages stored in the buffer are sent to the receiver. (Notice, if you run the application from Visual Studio, do not forget to set that the application shall be deployed on 'Windows Phone 7 Emulator'.) The client application uses the assembly built for the Windows Phone 7, Eneter.Messaging.Framework.Phone.dll.

using System;
using System.Windows;
using Eneter.Messaging.DataProcessing.Serializing;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.Composites;
using Eneter.Messaging.MessagingSystems.HttpMessagingSystem;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Microsoft.Phone.Controls;

namespace Phone7Sender
{
    public partial class MainPage : PhoneApplicationPage
    {
        // The message transferring numbers to be calculated.
        public class RequestMsg
        {
            public int Number1;
            public int Number2;
        }

        // Sender sending the request to calculate
        // two numbers and receiving the result.
        private IDuplexTypedMessageSender<int, RequestMsg> mySender;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            OpenConnection();
        }

        private void OpenConnection()
        {
            // Create Http messaging.
            // Note: The default constructor routes received
            // response messages into the Silverlight thread.
            //       If it is not desired, then it can be changed.
            IMessagingSystemFactory anUnderlyingMessaging = new HttpMessagingSystemFactory();

            // The cell-phone connection can be unstable.
            // Therefore, let's use the buffered messaging monitoring the connection
            // and with automatic reconnect in case of the disconnection.
            // Create buffered messaging, that will be able to work offline 1 minute.
            // During the offline time, the sent messages
            // are stored in the buffer and the framework tries
            // to reconnect.
            IMessagingSystemFactory aBufferedMessaging = 
                new BufferedMonitoredMessagingFactory(
                anUnderlyingMessaging, 
                new XmlStringSerializer(), 
                // maximum offline time
                TimeSpan.FromMinutes(1), 
                // how often the 'ping' checking the connection is invoked
                TimeSpan.FromMilliseconds(500),
                // maximum time, the response for the 'ping' shall be received
                TimeSpan.FromMilliseconds(1000)
                );
            IDuplexOutputChannel anOutputChannel = 
               aBufferedMessaging.CreateDuplexOutputChannel(
               "http://127.0.0.1:8034/Calculator/");

            // Create message sender - response receiver.
            IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
            mySender = aSenderFactory.CreateDuplexTypedMessageSender<int, RequestMsg>();
            mySender.ResponseReceived += OnResponseReceived;

            // Attach duplex output channel and be able to send
            // messages and receive response messages.
            mySender.AttachDuplexOutputChannel(anOutputChannel);
        }

        private void LayoutRoot_Unloaded(object sender, RoutedEventArgs e)
        {
            mySender.DetachDuplexOutputChannel();
        }

        private void SendButton_Click(object sender, RoutedEventArgs e)
        {
            // Create the request message.
            RequestMsg aMessage = new RequestMsg();
            aMessage.Number1 = int.Parse(Number1TextBox.Text);
            aMessage.Number2 = int.Parse(Number2TextBox.Text);

            // Send the message.
            // Note: If the connection is not available,
            //       the message will be stored in the buffer.
            //       We have set, the application can work offline maximum 1 minute.
            mySender.SendRequestMessage(aMessage);
        }

        private void OnResponseReceived(object sender, 
                     TypedResponseReceivedEventArgs<int> e)
        {
            if (e.ReceivingError == null)
            {
                // The response message was routed to the Silverlight thread.
                // Therefore, the value can be directly written to the UI control.
                ResultTextBox.Text = e.ResponseMessage.ToString();
            }
        }

    }
}

The following picture shows the communicating applications:

I hope you found the article useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ondrej_Uzovic
Architect
Slovakia Slovakia
My programming path started in 1987 when I got my first computer Sharp MZ-800.
It came with 8 bit CPU Z80, 64Kb RAM and the tape recorder. It was a great machine. I think I still have it somewhere.
I was fascinated and I started to write first programs. Eventually I became developer and software architect. I like innovations and clean nice solutions.

Comments and Discussions

 
QuestionDoes this solution works for a real device? Pinmemberprathapsimha2-Aug-12 21:06 
AnswerRe: Does this solution works for a real device? PinmemberOndrej_Uzovic3-Aug-12 3:19 
QuestionError PinmemberMember 244156710-Jan-12 10:40 
AnswerRe: Error PinmemberOndrej_Uzovic12-Jan-12 9:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 28 Mar 2011
Article Copyright 2011 by Ondrej_Uzovic
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid