WP7如何与桌面程序通信(译)
这是一个显示WP7如何跟一个独立的应用程序使用http执行简单通信的例子。
介绍
下面实现了一个.NET程序作为服务端并且WP7应用程序作为客户端的例子.这个服务计算两个数字并且返回结果.WP7应用程序使用这个
服务的计算并显示其结果。
有时手机网络连接是不稳定的、信号变弱或者可能短暂失去信号。一个好的应用程序能够处理这种情形使其正常工作。
下面的例子使用Eneter通讯框架,允许设置通信检测断开,自动尝试重新连接,并同时消息存储到缓冲区。然后,当连接再次可用时,存储在缓冲区的消息发送到接收者。
(非商业免费版本可以从http://www.eneter.net下载。开发者在线帮助http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html)
服务端应用程序
网络应用服务主要实现计算两数之和并且返回其结果。实现整个过程很简单,但是注意要有足够的用户权限才能运行http去监听应用程序,否则只能运行不能监听.
(在调试端口的时框架记录拒绝访问的错误)在调试时我建议用管理员的权限去执行。
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
{
//传递要进行数字计算的消息类
public class RequestMsg
{
public int Number1;
public int Number2;
}
class Program
{
//接收者收到要进行计算的数字并且响应其结果
static private IDuplexTypedMessageReceiver<int,RequestMsg> myReceiver;
static void Main(string[] args)
{
// 创建http消息
IMessagingSystemFactory anUnderlyingMessaging = new HttpMessagingSystemFactory();
// 网络不稳定我们可以使用缓冲消息监测连接并且万一断开连接时自动重新连接
// 如果在客户端ping的时间超过5秒,那么就认为客户端断开了连接,然后响应的消息存储在缓冲区
// 如果在15秒内有连接响应的消息发送到客户端
IMessagingSystemFactory aBufferedMessaging = new BufferedMonitoredMessagingFactory(anUnderlyingMessaging,new XmlStringSerializer(),
//客户端离线的最小时间
TimeSpan.FromMilliseconds(15000),
// 'ping' 的频率 – 不用于接收者
TimeSpan.FromMilliseconds(500),
//消息没有被接收ping的最大时间区
TimeSpan.FromMilliseconds(5000));
IDuplexInputChannel anInputChannel =aBufferedMessaging.CreateDuplexInputChannel("http://127.0.0.1:8034/Calculator/");
// 创建消息接收者 – 响应发送者
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 ...");
// 在指定地址附加双工输入通道开始监听
myReceiver.AttachDuplexInputChannel(anInputChannel);
Console.ReadLine();
myReceiver.DetachDuplexInputChannel();
}
//接收到请求时方法被调用
static private void OnMessageReceived(object sender,TypedRequestReceivedEventArgs<RequestMsg> e)
{
// 计算输入的两个数字.
if (e.ReceivingError == null)
{
int aResult = e.RequestMessage.Number1 +e.RequestMessage.Number2;
Console.WriteLine("{0} + {1} = {2}",
e.RequestMessage.Number1, e.RequestMessage.Number2, aResult);
// 发送返回的结果
myReceiver.SendResponseMessage(e.ResponseReceiverId, aResult);
}
}
}
}
客户端应用程序
WP7客户端应用程序发送计算两个数字请求并且显示其结果。
如果连接丢失,消息将被缓冲并且消息系统尝试自动重新连接。如果重新连接了存储在缓冲区的消息发送到接收者。
(注意如果在VS里面运行程序,不要忘了设置部署在WP7模拟器中。)
客户端使用WP程序集: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
{
//传递数字进行计算的消息类。
public class RequestMsg
{
public int Number1;
public int Number2;
}
// 发送者发送计算两个数字请求然后接收结果
private IDuplexTypedMessageSender<int, RequestMsg> mySender;
// 构造器
public MainPage()
{
InitializeComponent();
OpenConnection();
}
private void OpenConnection()
{
// 创建http 消息
// 注意: 默认构造函数接收响应消息到Silverlight线程
IMessagingSystemFactory anUnderlyingMessaging = new HttpMessagingSystemFactory();
// 手机设备连接不稳定,因此我们用缓冲消息去监测连接并且自动连接断开的情况
// 创建缓冲消息, 使其在离线一分钟的时候能够执行
// 在离线时,发送的消息存储在缓冲区并且框架尝试去自动重新连接
IMessagingSystemFactory aBufferedMessaging =
new BufferedMonitoredMessagingFactory( anUnderlyingMessaging,
new XmlStringSerializer(),
// 离线最长时间
TimeSpan.FromMinutes(1),
// 多久ping一次 检查连接是否可用
TimeSpan.FromMilliseconds(500),
//响应ping时发送的请求的最长时间
TimeSpan.FromMilliseconds(1000)
);
IDuplexOutputChannel anOutputChannel = aBufferedMessaging.CreateDuplexOutputChannel("http://127.0.0.1:8034/Calculator/"); // 创建消息发送者 – 响应接收者
IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
mySender = aSenderFactory.CreateDuplexTypedMessageSender<int, RequestMsg>();
mySender.ResponseReceived += OnResponseReceived;
// 附加双输出通道使其能够发送消息并且接收消息
mySender.AttachDuplexOutputChannel(anOutputChannel);
}
private void LayoutRoot_Unloaded(object sender,RoutedEventArgs e)
{
mySender.DetachDuplexOutputChannel();
}
private void SendButton_Click(object sender, RoutedEventArgs e)
{
// 创建请求消息
RequestMsg aMessage = new RequestMsg();
aMessage.Number1 = int.Parse(Number1TextBox.Text);
aMessage.Number2 = int.Parse(Number2TextBox.Text);
// 发送消息
// 注意: 如果连接不可用是消息将存储在缓冲区
// 我们已经设置应用程序能够在离线最多一分钟时能够工作
mySender.SendRequestMessage(aMessage);
}
private void OnResponseReceived(object sender,TypedResponseReceivedEventArgs<int> e)
{
if (e.ReceivingError == null)
{
// 响应消息路由到Silverlight线程。因此, 值能够直接显示在UI控件上.
ResultTextBox.Text = e.ResponseMessage.ToString();
}
}
}
}
下面的截图展示了通信应用。
作者:Ondrej_Uzovic
推荐阅读