Dev (Back & Front)ARTIGO

Windows Phone 7: como se comunicar com um aplicativo desktop

Neste artigo, mostro um simples
exemplo de como implementar a comunicação do Windows Phone 7 com a
aplicação autônoma .NET usando HTTP.

O exemplo abaixo implementa uma
simples aplicação .NET como serviço, e o aplicativo do Windows Phone 7 como um
cliente. O serviço calcula dois números e retorna o resultado. O cliente do Windows
Phone 7 então usa o serviço para fazer o cálculo e exibe o resultado.

Isso é típico para telefones
celulares, nos quais a conexão com a internet não é estável. O sinal pode
ficar fraco, ou ser temporariamente perdido. Um bom aplicativo deve ser capaz
de lidar com essa situação e não parar de trabalhar.

O exemplo abaixo usa o Framework Eneter
Messaging, que permite a configuração da comunicação que detecta desconexões, e
automaticamente tenta reconectar, enquanto armazena as mensagens enviadas no
buffer. Então, quando a conexão volta a estar disponível, as mensagens
armazenadas no buffer são enviadas para o receptor.

(Uma versão completa, não limitada e para uso não-comercial do framework pode
ser encontrada para download em http://www.eneter.net. A ajuda online para desenvolvedores pode ser encontrada
em http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html)

Aplicação de serviço

A aplicação de serviço
.NET é responsável pelo cálculo de dois números e por responder aos resultados.
Toda a implementação é muito simples. Por favor, note que, para executar o
aplicativo de escuta HTTP, você deve executá-lo sob direitos do usuários
suficientes. Caso contrário, a aplicação será executada, mas não escutada. (O
framework irá gerar um erro de acesso negado na porta de debugação). Para
objetivos de debugação, recomendo executá-lo sob os direitos do administrador.

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(),
TimeSpan.FromMilliseconds(15000), // maximum time, the client can be offline
TimeSpan.FromMilliseconds(500), // 'ping' frequency - this is not applicable for the receiver
TimeSpan.FromMilliseconds(5000) // maximum time, the 'ping' message does not have to be received
);


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);
}
}
}
}

Aplicação do cliente

A aplicação do cliente do Windows Phone 7 envia pedidos para calcular dois
números e exibir os resultados. Se a conexão é perdida, as mensagens são
armazenadas, e o sistema de mensagens tenta se reconectar automaticamente.

Então, se a conexão é restabelecida, as mensagens armazenadas no buffer são
enviadas para o receptor. (Se você executar a aplicação a partir do Visual
Studio, não se esqueça de que a aplicação deve ser desenvolvida no ‘Windows Phone
7 Emulator’.) A aplicação do cliente usa a montagem construída para o 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(),
TimeSpan.FromMinutes(1), // maximum offline time
TimeSpan.FromMilliseconds(500), // how often the 'ping' checking the connection is invoked
TimeSpan.FromMilliseconds(1000) // maximum time, the response for the 'ping' shall be received
);
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();
}
}

}
}

A
figura abaixo mostra as aplicações de comunicação:

Espero
que tenha achado este artigo útil.  

?

Texto original disponível em http://eneter.blogspot.com/2011/03/phone-7-how-to-communicate-with-desktop.html

É eslovaco e referência em arquitetura de software nos EUA. Colabora com o iMasters em inglês (os artigos são traduzidos pelo iMasters) e é mantenedor do blog eneter.net.

Ver perfil