WP7应用开发笔记(5) 通信设计
2012-05-19 19:55
344 查看
WP7支持的通信方式
1. HTTP协议
主要是由WebClient或HttpWebRequest两个类提供,直接封装HTTP协议访问Web站点。最常用的通信方式。2. WCF
WCF作为MS大力推广的通信方案非常强大,但是到了WP7上就变成了太监,只支持简单的BasicHttpBinding而且还有非常多的限制。3 Socket
7.1SDK里新增的通信方式,支持TCP和UDP但只能使用异步的SocketAsyncEventArgs事件方式,也有不少限制。选择通信方式
因为同时需要考虑到服务器端的实现,在服务器端尽量精简,最好不要有什么IIS之类大型依赖。对应是服务器端实现方式如下:
HTTP协议 | HttpListener |
WCF | Wcf应用程序宿主 |
Socket | Socket |
SOCKET协议选择
而Socket分为TCP和UDP,为了稳定选择了有重传功能和回复的TCP(其实UDP也不是什么问题)。TCP需要3次握手来维持链接,但是按照“偶尔连接”(Occasionally Connect)的设计准则,我不能让手机一直保持连接,而且断线检查也是个麻烦事。
所以决定采用HTTP1.0类似的短链接方式,就是连上、发一条消息、然后断开的流程(暂时没有回复)
应用层消息报文设计
这个程序比较简单设计的报文也很简单,因为内网传输不需要考虑身份验证,加密、完整性等,而且短链接不会遇到粘包和拆包之类的,真是太轻松了。
报文结构如下
Length | 长度 | 4字节 int |
Action | 动作 | 32字节 UTF8编码 |
Context | 内容 | 长度由Length描述 UTF8编码 |
Action目前只有”TAP”按键 一种
Context表示按键的类型 有2种分类
一种是 Keyboard 直接对应键盘的键名称
另一种是 Media 媒体控制用 包括TogglePlayPause(播放暂停)、Forward(前进)、Backward(后退)IncreaseVolume(提高音量)等
表示方式是“Media.TogglePlayPause”
Media 协议表
View Code
public class SendCommandCompletedEventArgs : EventArgs { public bool Success { get; internal set; } public string ErrMessage { get; internal set; } } public class Client { const int ActionSize = 32; const int BufferSize = 1024; public event EventHandler<SendCommandCompletedEventArgs> SendCommandCompleted; private void OnSendCommandCompleted(SendCommandCompletedEventArgs e) { EventHandler<SendCommandCompletedEventArgs> handler = SendCommandCompleted; if (handler != null) handler(this, e); } public Client() { } public void SendCommandAsync(EndPoint endPoint, string action, string command) { var actionBuffer = Encoding.UTF8.GetBytes(action); var contextBuffer = Encoding.UTF8.GetBytes(command); var bufferSize = contextBuffer.Length + ActionSize + 4; var lengthBuffer = BitConverter.GetBytes(contextBuffer.Length); var buffer = new byte[BufferSize]; int offset = 0; Array.Copy(lengthBuffer, 0, buffer, offset, lengthBuffer.Length); offset += 4; Array.Clear(buffer, offset, ActionSize); Array.Copy(actionBuffer, 0, buffer, offset, actionBuffer.Length); offset += ActionSize; Array.Copy(contextBuffer, 0, buffer, offset, contextBuffer.Length); var socketAsyncEventArgs = new SocketAsyncEventArgs { UserToken = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) }; socketAsyncEventArgs.Completed += AsyncCompleted; socketAsyncEventArgs.SetBuffer(buffer, 0, bufferSize); socketAsyncEventArgs.RemoteEndPoint = endPoint; ProcessConnect(socketAsyncEventArgs); } #region Private private void ProcessConnect(SocketAsyncEventArgs e) { var socket = (Socket)e.UserToken; bool willRaiseEvent = socket.ConnectAsync(e); if (!willRaiseEvent) { ConnectCompleted(e); } } private void ProcessSend(SocketAsyncEventArgs e) { var socket = (Socket)e.UserToken; bool willRaiseEvent = socket.SendAsync(e); if (!willRaiseEvent) { SendCompleted(e); } } private void AsyncCompleted(object sender, SocketAsyncEventArgs e) { switch (e.LastOperation) { case SocketAsyncOperation.Connect: ConnectCompleted(e); break; case SocketAsyncOperation.Send: SendCompleted(e); break; case SocketAsyncOperation.Receive: ReceiveCompleted(e); break; default: return; } } private void ReceiveCompleted(SocketAsyncEventArgs e) { } private void ConnectCompleted(SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { ProcessSend(e); } else { OnSendCommandCompleted(new SendCommandCompletedEventArgs { Success = false, ErrMessage = "接收器无法连接" }); } } private void SendCompleted(SocketAsyncEventArgs e) { var socket = (Socket)e.UserToken; socket.Close(); if (e.SocketError == SocketError.Success) { OnSendCommandCompleted(new SendCommandCompletedEventArgs { Success = true }); } else { OnSendCommandCompleted(new SendCommandCompletedEventArgs { Success = false, ErrMessage = "发送命令失败" }); } } #endregion }
转自:/article/5295990.html
相关文章推荐
- WP7应用开发笔记 TiltEffect为控件添加倾斜的触控响应效果
- Android 应用开发笔记 - 应用程序设计基础
- 学习WP7应用开发的笔记--在App和Page中使用资源集合的注意点1
- WP7应用开发笔记(9) 应用程序栏
- WP7应用开发笔记(13) MVVM
- WP7应用开发笔记(14) 使用Caliburn Micro简化MVVM
- 6-读书笔记----iOS开发指南:从零基础到App Store上架--iOS-iPhone与iPad应用开发的差异和iOS分层架构设计
- WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片
- WP7应用开发笔记-豆知识 使用本地值的时候应该多考虑使用系统主题资源
- WP7应用开发笔记(10) 导航
- WP7应用开发笔记-插曲 小心使用MessageBox
- WP7应用开发笔记(15) 推送通知
- WindowsPhone8 应用开发学习笔记(三) - UDP通信
- WP7应用开发笔记(11) 自定义按钮
- WP7应用开发笔记(16) 本地Toast 提示
- WP7应用开发笔记(17) 提交应用
- 我的WP7应用开发笔记系列
- 学习WP7应用开发的笔记--秒分时针的角度计算
- Android应用开发笔记(13): Android移动应用界面的模板化设计
- WP7应用开发笔记(18) 本地化与多语言