wp8使用Beetle.NetPackage实现基于TCP通讯的订单查询

在新版本的Beetle.NetPackage中提供了对Protobuf和Controller的支持,所以在WP8下使用Beetle.NetPackage进行基于TCP的数据交互则一件非常简单事情.下面通过组件在WP8下简单实现基于TCP通讯的订单在线查询功能.

协议定义

为了简化交互数据的处理在这里使用Protobuf来描述数据交互,通过Protobuf制订一系列的请求和应答对象来代替平常在TCP下繁琐的数据流处理过程.下面通过Protobuf来描述订单查询的通讯协议.

  1 [ProtoContract]
  2     public class GetCustomer
  3     {
  4         [ProtoMember(1)]
  5         public string Name { get; set; }
  6     }
  7 
  8     [ProtoContract]
  9     public class GetCustomerResponse
 10     {
 11 
 12         [ProtoMember(1)]
 13         public IList<Customer> Items
 14         {
 15             get;
 16             set;
 17         }
 18 
 19     }
 20 
 21     [ProtoContract]
 22     public class Customer
 23     {
 24         [ProtoMember(1)]
 25         public string ID
 26         {
 27             get;
 28             set;
 29         }
 30         [ProtoMember(2)]
 31         public string Name
 32         {
 33             get;
 34             set;
 35         }
 36         public override string ToString()
 37         {
 38             return Name;
 39         }
 40     }
 41 
 42     [ProtoContract]
 43     public class GetEmployee
 44     {
 45         [ProtoMember(1)]
 46         public string Name { get; set; }
 47     }
 48 
 49     [ProtoContract]
 50     public class GetEmployeeResponse
 51     {
 52         [ProtoMember(1)]
 53         public IList<Employee> Items
 54         {
 55             get;
 56             set;
 57         }
 58     }
 59 
 60     [ProtoContract]
 61     public class Employee
 62     {
 63 
 64         [ProtoMember(1)]
 65         public string ID
 66         {
 67             get;
 68             set;
 69         }
 70         [ProtoMember(2)]
 71         public string Name
 72         {
 73             get;
 74             set;
 75         }
 76         public override string ToString()
 77         {
 78             return Name;
 79         }
 80         
 81     }
 82 
 83     [ProtoContract]
 84     public class OrderSearch
 85     {
 86         [ProtoMember(1)]
 87         public string Employee { get; set; }
 88         [ProtoMember(2)]
 89         public int PageIndex { get; set; }
 90         [ProtoMember(3)]
 91         public string Customer { get; set; }
 92         [ProtoMember(4)]
 93         public string FromDate { get; set; }
 94         [ProtoMember(5)]
 95         public string ToDate { get; set; }
 96     }
 97 
 98     [ProtoContract]
 99     public class OrderSearchResponse
100     {
101         [ProtoMember(1)]
102         public IList<Order> Items
103         {
104             get;
105             set;
106         }
107         [ProtoMember(2)]
108         public int PageIndex
109         {
110             get;
111             set;
112         }
113         [ProtoMember(3)]
114         public int Pages
115         {
116             get;
117             set;
118         }
119     }
120 
121     [ProtoContract]
122     public class Order
123     {
124         [ProtoMember(1)]
125         public string OrderID { get; set; }
126         [ProtoMember(2)]
127         public string Employee { get; set; }
128         [ProtoMember(3)]
129         public string Customer { get; set; }
130         [ProtoMember(4)]
131         public string OrderDate { get; set; }
132         [ProtoMember(5)]
133         public string RequiredDate { get; set; }
134         [ProtoMember(6)]
135         public string ShippedDate { get; set; }
136         [ProtoMember(7)]
137         public string ShipName { get; set; }
138         [ProtoMember(8)]
139         public string ShipAddress { get; set; }
140         [ProtoMember(9)]
141         public string ShipCity { get; set; }
142         [ProtoMember(10)]
143         public string ShipRegion { get; set; }
144     }
145 
146     [ProtoContract]
147     public class GetOrderDetail
148     {
149         [ProtoMember(1)]
150         public string OrderID { get; set; }
151     }
152 
153     [ProtoContract]
154     public class GetOrderDetailResponse
155     {
156         [ProtoMember(1)]
157         public IList<OrderDetail> Items
158         {
159             get;
160             set;
161         }
162     }
163 
164     [ProtoContract]
165     public class OrderDetail
166     {
167         [ProtoMember(1)]
168         public string OrderID { get; set; }
169         [ProtoMember(2)]
170         public string Product { get; set; }
171         [ProtoMember(3)]
172         public double UnitPrice { get; set; }
173         [ProtoMember(4)]
174         public int Quantity { get; set; }
175         [ProtoMember(5)]
176         public float Discount { get; set; }
177     }
View Code

由于这里使用了protobuf-net,所以通过类和特性来结合,其实规范方便其他平台处理还是建议使用proto文件描述来生成对应的类,这样可以方便生成C++,JAVA等不同平台的交互对象.

定义TCP通讯对象

通过Beetle.NetPackage对protobuf的支持,在WP8下建立相应的TCP通讯是件非常简单的事情.

1 Beetle.NetPackage.ProtoPakcage.Register(typeof(MainPage).Assembly);
2             if (mClient == null)
3             {
4                 mClient = new Beetle.NetPackage.NetClient("192.168.0.104", 9088, new Beetle.NetPackage.ProtoPakcage(), this);
5                 mClient.LittleEndian = false;
6             }
7             mClient.Connect();

在使用protobuf前通过ProtoPakcage.Register把程序集下面对应的protobuf消息注册到组件中,然后创建相应的NetClient就可以进行数据通讯.在这里为了和android交互兼容把client的LittleEndian属性设置成false即在处理数据过程采用高字序作为一些数据类型的处理方式.

消息路由分发

在新版本的Beetle.NetPackage中提供简单的消息路由功能,因此在编写消息接收处理的时候再也不需要通过if来判断不同消息去调用方法.使用消息路由并不需开发人员定义复杂的消息规则,只需要定义相应消息类型的参数即可让组件帮助完成这个事情.

 1 public void OnSearchOrderResponse(Beetle.NetPackage.NetClient client, OrderSearchResponse e)
 2         {
 3             if (e.Items == null)
 4                 lstOrders.ItemsSource = null;
 5             else
 6                 lstOrders.ItemsSource = e.Items.ToList();
 7             mPageIndex = e.PageIndex;
 8             mPages = e.Pages;
 9         }
10 
11         public void OnGetEmployee(Beetle.NetPackage.NetClient client, GetEmployeeResponse e)
12         {
13             mEmployees = e.Items;
14             lstEmployee.ItemsSource = e.Items.ToList();
15         }
16         public void OnGetCustomer(Beetle.NetPackage.NetClient client, GetCustomerResponse e)
17         {
18             mCustomers = e.Items;
19             lstCustomer.ItemsSource = e.Items.ToList();
20 
21         }
22         public void OnGetOrderDetail(Beetle.NetPackage.NetClient client, GetOrderDetailResponse e)
23         {
24             DialogOrderDetail detail = new DialogOrderDetail();
25             CustomMessageBox mOrderDetailDialog = new CustomMessageBox
26             {
27                 Content = detail,
28                 Title = "OrderDetail",
29                 RightButtonContent = "OK"
30             };
31             detail.ListSelector.ItemsSource = e.Items.ToList();
32             mOrderDetailDialog.Show();
33         }

以上是制定不同消息的处理过程,在接收消息的时候触发这些过程只需要简单地调用Controller.Invoke方法即可完成.

1 public void ClientReceive(Beetle.NetPackage.NetClient client, object message)
2         {
3             this.Dispatcher.BeginInvoke(() =>
4             {
5                 Beetle.NetPackage.Controller.Invoke(this, mClient, message);
6             });
7         }

在消息接收方法中调用Controller.Invoke组件会自动匹配相应消息处理的方法并调用,由于是组件自动匹配所以在制定方法的过程也需要遵循一个规则,就是在一个对象中对应消息处理的方法必须是唯一的. 

运行效果

  

总结

通过Beetle.NetPackage只需要很少量的代码就能完成基于TCP的对象数据交互处理,而开发者是完全不用关心下层的协议处理细节,Beetle.NetPackage不仅仅提供对wp8的支持,还提供对flash和android的支持.

下载sample 

 组件开源官网:https://beetlenp.codeplex.com/

posted @ 2013-09-23 09:57  beetlex  阅读(1364)  评论(2编辑  收藏  举报