[源码下载]

重新想象 Windows 8 Store Apps (63) - 通信: WebSocket

作者:webabcd

介绍
重新想象 Windows 8 Store Apps 之 通信

  • Socket - 与 WebSocket 服务端做 Text 通信
  • Socket - 与 WebSocket 服务端做 Stream(Binary) 通信

示例
WebSocket 的服务端
WebServer/WebSocketServer.ashx.cs

  1. /*
  2. * WebSocket 协议的服务端
  3. *
  4. * 需要在 iis 启用 WebSocket 协议:控制面板 -> 程序和功能 -> 启用或关闭 Windows 功能 -> 开启 iis 的 WebSocket 协议
  5. */
  6.  
  7. using System;
  8. using System.IO;
  9. using System.Net.WebSockets;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Web;
  13.  
  14. namespace WebServer
  15. {
  16. public class WebSocketServer : IHttpHandler
  17. {
  18. // 接收数据的缓冲区的最大大小
  19. private int _maxBufferSize = * ;
  20.  
  21. public void ProcessRequest(HttpContext context)
  22. {
  23. try
  24. {
  25. // HttpContext.AcceptWebSocketRequest() - 接受一个 WebSocket 请求
  26. context.AcceptWebSocketRequest(async wsContext => // AspNetWebSocketContext
  27. {
  28. try
  29. {
  30. byte[] receiveBuffer = new byte[_maxBufferSize];
  31. ArraySegment<byte> buffer = new ArraySegment<byte>(receiveBuffer);
  32.  
  33. // AspNetWebSocketContext.WebSocket - 获取当前上下文的 WebSocket 对象
  34. WebSocket socket = wsContext.WebSocket;
  35.  
  36. // HTTP 握手完成
  37. if (socket.State == WebSocketState.Open)
  38. {
  39. var outputString = "WebSocket Connected: " + DateTime.Now.ToString("mm:ss");
  40. ArraySegment<byte> outputBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(outputString));
  41.  
  42. // WebSocket.SendAsync() - 发送数据
  43. // WebSocketMessageType.Text - 发送的是文本数据
  44. // WebSocketMessageType.Binary - 发送的是二进制数据
  45. await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
  46. }
  47.  
  48. // HTTP 握手完成
  49. while (socket.State == WebSocketState.Open)
  50. {
  51. // WebSocket.ReceiveAsync() - 接收数据,返回 WebSocketReceiveResult 对象
  52. WebSocketReceiveResult receiveResult = await socket.ReceiveAsync(buffer, CancellationToken.None);
  53.  
  54. // WebSocketReceiveResult.MessageType - 接收到的数据的类型(WebSocketMessageType 枚举)
  55. // WebSocketMessageType.Text - 收到的是文本数据
  56. // WebSocketMessageType.Binary - 收到的是二进制数据
  57. // WebSocketMessageType.Close - 收到的是来自客户端的 WebSocket 关闭的消息
  58. if (receiveResult.MessageType == WebSocketMessageType.Close)
  59. {
  60. // WebSocket.CloseAsync() - 关闭 WebSocket
  61. await socket.CloseAsync(
  62. receiveResult.CloseStatus.GetValueOrDefault(),
  63. receiveResult.CloseStatusDescription,
  64. CancellationToken.None);
  65.  
  66. return;
  67. }
  68.  
  69. int offset = receiveResult.Count;
  70.  
  71. // WebSocketReceiveResult.EndOfMessage - 消息是否被完全接收
  72. while (receiveResult.EndOfMessage == false)
  73. {
  74. // WebSocket.ReceiveAsync() - 接收数据,返回 WebSocketReceiveResult 对象
  75. receiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer, offset, _maxBufferSize - offset), CancellationToken.None);
  76. offset += receiveResult.Count;
  77. }
  78.  
  79. // 收到文本数据
  80. if (receiveResult.MessageType == WebSocketMessageType.Text)
  81. {
  82. string receivedText = Encoding.UTF8.GetString(receiveBuffer, , offset);
  83. string sendText = "server to client: \"" + receivedText + "\"";
  84.  
  85. // 发送文本数据到客户端
  86. ArraySegment<byte> outputBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendText));
  87. await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
  88. }
  89. // 收到二进制数据
  90. else if (receiveResult.MessageType == WebSocketMessageType.Binary)
  91. {
  92. string sendText = "server to client: binary message received, size: " + receiveResult.Count + " bytes";
  93.  
  94. // 发送文本数据到客户端
  95. ArraySegment<byte> outputBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendText));
  96. await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
  97. }
  98. }
  99. }
  100. catch (Exception ex)
  101. {
  102.  
  103. }
  104. });
  105. }
  106. catch (Exception ex)
  107. {
  108.  
  109. }
  110. }
  111.  
  112. public bool IsReusable
  113. {
  114. get
  115. {
  116. return false;
  117. }
  118. }
  119. }
  120. }

1、演示如何通过 MessageWebSocket 与 WebSocket 服务端做 Text 通信
Communication/Socket/MessageWebSocketDemo.xaml

  1. <Page
  2. x:Class="XamlDemo.Communication.Socket.MessageWebSocketDemo"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:XamlDemo.Communication.Socket"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d">
  9.  
  10. <Grid Background="Transparent">
  11. <StackPanel Margin="120 0 0 0" Orientation="Horizontal">
  12.  
  13. <StackPanel>
  14. <Button Name="btnTextDemo" Content="与 WebSocket 服务端做 Text 通信" Click="btnTextDemo_Click" />
  15. <Button Name="btnClose" Content="Close" Click="btnClose_Click" Margin="0 10 0 0" />
  16. </StackPanel>
  17.  
  18. <TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" Margin="20 0 0 0" />
  19.  
  20. </StackPanel>
  21. </Grid>
  22. </Page>

Communication/Socket/MessageWebSocketDemo.xaml.cs

  1. /*
  2. * 演示如何通过 MessageWebSocket 与 WebSocket 服务端做 Text 通信
  3. *
  4. * 注:需要在 Package.appxmanifest 中增加配置 <Capability Name="privateNetworkClientServer" /> 和 <Capability Name="internetClient" />
  5. */
  6.  
  7. using System;
  8. using Windows.Networking.Sockets;
  9. using Windows.Storage.Streams;
  10. using Windows.UI.Core;
  11. using Windows.UI.Xaml;
  12. using Windows.UI.Xaml.Controls;
  13. using Windows.Web;
  14.  
  15. namespace XamlDemo.Communication.Socket
  16. {
  17. public sealed partial class MessageWebSocketDemo : Page
  18. {
  19. // WebSocket 协议的服务端地址(服务端代码参见:WebServer/WebSocketServer.cs)
  20. private Uri _serverUri = new Uri("ws://localhost:86/WebSocketServer.ashx");
  21.  
  22. // MessageWebSocket - 用于与 WebSocket 服务端做 Message 通信(可以是 utf8 或 binary)
  23. private MessageWebSocket _socket;
  24.  
  25. // 用于发送数据
  26. DataWriter _dataWriter;
  27.  
  28. public MessageWebSocketDemo()
  29. {
  30. this.InitializeComponent();
  31. }
  32.  
  33. private async void btnTextDemo_Click(object sender, RoutedEventArgs e)
  34. {
  35. try
  36. {
  37. if (_socket == null)
  38. {
  39. lblMsg.Text += "connecting to: " + _serverUri.ToString();
  40. lblMsg.Text += Environment.NewLine;
  41.  
  42. _socket = new MessageWebSocket();
  43. // 发送的消息的类型 Utf8 或 Binary
  44. _socket.Control.MessageType = SocketMessageType.Utf8;
  45. // 接收到消息时所触发的事件
  46. _socket.MessageReceived += _socket_MessageReceived;
  47.  
  48. // WebSocket 关闭时所触发的事件
  49. _socket.Closed += async (senderSocket, args) =>
  50. {
  51. await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  52. {
  53. // WebSocketClosedEventArgs.Code - 关闭原因的状态吗
  54. // WebSocketClosedEventArgs.Reason - 关闭原因的详细信息
  55. lblMsg.Text += "socket closed - code: " + args.Code + ", reason: " + args.Reason;
  56. lblMsg.Text += Environment.NewLine;
  57.  
  58. if (_socket != null)
  59. {
  60. _socket.Dispose();
  61. _socket = null;
  62. }
  63. });
  64. };
  65.  
  66. // 连接指定的 WebSocket 服务
  67. await _socket.ConnectAsync(_serverUri);
  68. // 根据 MessageWebSocket 的 OutputStream,实例化一个 DataWriter,以便发数据到服务端
  69. _dataWriter = new DataWriter(_socket.OutputStream);
  70.  
  71. lblMsg.Text += "connected";
  72. lblMsg.Text += Environment.NewLine;
  73. }
  74.  
  75. string message = "hello " + DateTime.Now.ToString("hh:mm:ss");
  76. lblMsg.Text += "send: " + message;
  77. lblMsg.Text += Environment.NewLine;
  78.  
  79. // 发送数据到服务端
  80. _dataWriter.WriteString(message);
  81. await _dataWriter.StoreAsync();
  82.  
  83. lblMsg.Text += "sent";
  84. lblMsg.Text += Environment.NewLine;
  85. }
  86. catch (Exception ex)
  87. {
  88. if (_socket != null)
  89. {
  90. _socket.Dispose();
  91. _socket = null;
  92. }
  93.  
  94. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  95.  
  96. lblMsg.Text += "errStatus: " + errStatus.ToString();
  97. lblMsg.Text += Environment.NewLine;
  98. lblMsg.Text += ex.ToString();
  99. lblMsg.Text += Environment.NewLine;
  100. }
  101. }
  102.  
  103. void _socket_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
  104. {
  105. try
  106. {
  107. // MessageWebSocketMessageReceivedEventArgs.MessageType - 收到的数据的类型 Utf8 或 Binary
  108. // MessageWebSocketMessageReceivedEventArgs.GetDataReader() - 获取收到的数据的 DataReader 对象,用于读取接收到的数据
  109. using (DataReader reader = args.GetDataReader())
  110. {
  111. reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
  112. string read = reader.ReadString(reader.UnconsumedBufferLength);
  113.  
  114. var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  115. {
  116. lblMsg.Text += "received: " + read;
  117. lblMsg.Text += Environment.NewLine;
  118. });
  119. }
  120. }
  121. catch (Exception ex)
  122. {
  123. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  124.  
  125. lblMsg.Text += "errStatus: " + errStatus.ToString();
  126. lblMsg.Text += Environment.NewLine;
  127. lblMsg.Text += ex.ToString();
  128. lblMsg.Text += Environment.NewLine;
  129. }
  130. }
  131.  
  132. private void btnClose_Click(object sender, RoutedEventArgs e)
  133. {
  134. try
  135. {
  136. if (_socket != null)
  137. {
  138. lblMsg.Text += "socket closing";
  139. lblMsg.Text += Environment.NewLine;
  140.  
  141. // 关闭 WebSocket,可以指定 code 和 reason(此处指定的 code 和 reason 可以在 MessageWebSocket.Closed 事件中获取)
  142. _socket.Close(, "用户在客户端关闭了 WebSocket");
  143. _socket = null;
  144. }
  145. }
  146. catch (Exception ex)
  147. {
  148. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  149.  
  150. lblMsg.Text += "errStatus: " + errStatus.ToString();
  151. lblMsg.Text += Environment.NewLine;
  152. lblMsg.Text += ex.ToString();
  153. lblMsg.Text += Environment.NewLine;
  154. }
  155. }
  156. }
  157. }

2、演示如何通过 StreamWebSocket 与 WebSocket 服务端做 Stream(Binary) 通信
Communication/Socket/StreamWebSocketDemo.xaml

  1. <Page
  2. x:Class="XamlDemo.Communication.Socket.StreamWebSocketDemo"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:XamlDemo.Communication.Socket"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d">
  9.  
  10. <Grid Background="Transparent">
  11. <StackPanel Margin="120 0 0 0" Orientation="Horizontal">
  12.  
  13. <StackPanel>
  14. <Button Name="btnBinaryDemo" Content="与 WebSocket 服务端做 Binary 通信" Click="btnBinaryDemo_Click" />
  15. <Button Name="btnClose" Content="Close" Click="btnClose_Click" Margin="0 10 0 0" />
  16. </StackPanel>
  17.  
  18. <TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" Margin="20 0 0 0" />
  19.  
  20. </StackPanel>
  21. </Grid>
  22. </Page>

Communication/Socket/StreamWebSocketDemo.xaml.cs

  1. /*
  2. * 演示如何通过 StreamWebSocket 与 WebSocket 服务端做 Stream(Binary) 通信
  3. *
  4. * 注:需要在 Package.appxmanifest 中增加配置 <Capability Name="privateNetworkClientServer" /> 和 <Capability Name="internetClient" />
  5. */
  6.  
  7. using System;
  8. using Windows.Networking.Sockets;
  9. using Windows.Storage.Streams;
  10. using Windows.UI.Core;
  11. using Windows.UI.Xaml;
  12. using Windows.UI.Xaml.Controls;
  13. using Windows.Web;
  14. using System.Runtime.InteropServices.WindowsRuntime;
  15. using System.Threading.Tasks;
  16. using System.IO;
  17.  
  18. namespace XamlDemo.Communication.Socket
  19. {
  20. public sealed partial class StreamWebSocketDemo : Page
  21. {
  22. // WebSocket 协议的服务端地址(服务端代码参见:WebServer/WebSocketServer.cs)
  23. private Uri _serverUri = new Uri("ws://localhost:86/WebSocketServer.ashx");
  24.  
  25. // StreamWebSocket - 用于与 WebSocket 服务端做 Stream 通信(只能是 binary)
  26. private StreamWebSocket _socket;
  27.  
  28. public StreamWebSocketDemo()
  29. {
  30. this.InitializeComponent();
  31. }
  32.  
  33. private async void btnBinaryDemo_Click(object sender, RoutedEventArgs e)
  34. {
  35. try
  36. {
  37. if (_socket == null)
  38. {
  39. lblMsg.Text += "connecting to: " + _serverUri.ToString();
  40. lblMsg.Text += Environment.NewLine;
  41.  
  42. _socket = new StreamWebSocket();
  43.  
  44. // WebSocket 关闭时所触发的事件
  45. _socket.Closed += async (senderSocket, args) =>
  46. {
  47. await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  48. {
  49. // WebSocketClosedEventArgs.Code - 关闭原因的状态吗
  50. // WebSocketClosedEventArgs.Reason - 关闭原因的详细信息
  51. lblMsg.Text += "socket closed - code: " + args.Code + ", reason: " + args.Reason;
  52. lblMsg.Text += Environment.NewLine;
  53.  
  54. if (_socket != null)
  55. {
  56. _socket.Dispose();
  57. _socket = null;
  58. }
  59. });
  60. };
  61.  
  62. // 连接指定的 WebSocket 服务
  63. await _socket.ConnectAsync(_serverUri);
  64.  
  65. // 新开线程,用于接收数据
  66. Task receiving = Task.Factory.StartNew(ReceiveData, _socket.InputStream.AsStreamForRead(), TaskCreationOptions.LongRunning);
  67.  
  68. // 新开线程,用于发送数据
  69. Task sending = Task.Factory.StartNew(SendData, _socket.OutputStream, TaskCreationOptions.LongRunning);
  70.  
  71. lblMsg.Text += "connected";
  72. lblMsg.Text += Environment.NewLine;
  73. }
  74. }
  75. catch (Exception ex)
  76. {
  77. if (_socket != null)
  78. {
  79. _socket.Dispose();
  80. _socket = null;
  81. }
  82.  
  83. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  84.  
  85. lblMsg.Text += "errStatus: " + errStatus.ToString();
  86. lblMsg.Text += Environment.NewLine;
  87. lblMsg.Text += ex.ToString();
  88. lblMsg.Text += Environment.NewLine;
  89. }
  90. }
  91.  
  92. // 发送数据
  93. private async void SendData(object state)
  94. {
  95. // 自定义需要发送的二进制数据
  96. byte[] data = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
  97.  
  98. try
  99. {
  100. IOutputStream writeStream = (IOutputStream)state;
  101.  
  102. while (true)
  103. {
  104. var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  105. {
  106. lblMsg.Text += "send: " + data.Length.ToString() + " 字节的数据";
  107. lblMsg.Text += Environment.NewLine;
  108. });
  109.  
  110. // 发送 stream 数据
  111. await writeStream.WriteAsync(data.AsBuffer());
  112.  
  113. var ignore2 = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  114. {
  115. lblMsg.Text += "sent";
  116. lblMsg.Text += Environment.NewLine;
  117. });
  118.  
  119. await Task.Delay(TimeSpan.FromSeconds());
  120. }
  121. }
  122. catch (ObjectDisposedException)
  123. {
  124. var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  125. {
  126. lblMsg.Text += "用于发送数据的后台线程已经停止";
  127. lblMsg.Text += Environment.NewLine;
  128. });
  129. }
  130. catch (Exception ex)
  131. {
  132. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  133.  
  134. var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  135. {
  136. lblMsg.Text += "errStatus: " + errStatus.ToString();
  137. lblMsg.Text += Environment.NewLine;
  138. lblMsg.Text += ex.ToString();
  139. lblMsg.Text += Environment.NewLine;
  140. });
  141. }
  142. }
  143.  
  144. // 接收数据
  145. private async void ReceiveData(object state)
  146. {
  147. // 用于接收数据的缓冲区
  148. byte[] readBuffer = new byte[];
  149.  
  150. int bytesReceived = ;
  151. try
  152. {
  153. Stream readStream = (Stream)state;
  154.  
  155. while (true)
  156. {
  157. // 接收数据
  158. int read = await readStream.ReadAsync(readBuffer, , readBuffer.Length);
  159. bytesReceived += read;
  160.  
  161. await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  162. {
  163. lblMsg.Text += "received: " + System.Text.Encoding.UTF8.GetString(readBuffer, , read);
  164. lblMsg.Text += Environment.NewLine;
  165. lblMsg.Text += "累计已收到 " + bytesReceived.ToString() + " 字节的数据";
  166. lblMsg.Text += Environment.NewLine;
  167. });
  168. }
  169. }
  170. catch (ObjectDisposedException)
  171. {
  172. var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  173. {
  174. lblMsg.Text += "用于接收数据的后台线程已经停止";
  175. lblMsg.Text += Environment.NewLine;
  176. });
  177. }
  178. catch (Exception ex)
  179. {
  180. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  181.  
  182. var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  183. {
  184. lblMsg.Text += "errStatus: " + errStatus.ToString();
  185. lblMsg.Text += Environment.NewLine;
  186. lblMsg.Text += ex.ToString();
  187. lblMsg.Text += Environment.NewLine;
  188. });
  189. }
  190. }
  191.  
  192. private void btnClose_Click(object sender, RoutedEventArgs e)
  193. {
  194. try
  195. {
  196. if (_socket != null)
  197. {
  198. lblMsg.Text += "socket closing";
  199. lblMsg.Text += Environment.NewLine;
  200.  
  201. // 关闭 WebSocket,可以指定 code 和 reason(此处指定的 code 和 reason 可以在 MessageWebSocket.Closed 事件中获取)
  202. _socket.Close(, "用户在客户端关闭了 WebSocket");
  203. _socket = null;
  204. }
  205. }
  206. catch (Exception ex)
  207. {
  208. WebErrorStatus errStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
  209.  
  210. lblMsg.Text += "errStatus: " + errStatus.ToString();
  211. lblMsg.Text += Environment.NewLine;
  212. lblMsg.Text += ex.ToString();
  213. lblMsg.Text += Environment.NewLine;
  214. }
  215. }
  216. }
  217. }

OK
[源码下载]

重新想象 Windows 8 Store Apps (63) - 通信: WebSocket的更多相关文章

  1. 重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化

    [源码下载] 重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化 作者:webabcd 介绍重新想象 Windows 8 Store Apps ...

  2. 重新想象 Windows 8 Store Apps (61) - 通信: http, oauth

    [源码下载] 重新想象 Windows 8 Store Apps (61) - 通信: http, oauth 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 通信 ...

  3. 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP

    [源码下载] 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP 作者:webabcd 介绍重新想象 Windows 8 Store ...

  4. 重新想象 Windows 8 Store Apps 系列文章索引

    [源码下载][重新想象 Windows 8.1 Store Apps 系列文章] 重新想象 Windows 8 Store Apps 系列文章索引 作者:webabcd 1.重新想象 Windows ...

  5. 重新想象 Windows 8 Store Apps (66) - 后台任务: 下载和上传

    [源码下载] 重新想象 Windows 8 Store Apps (66) - 后台任务: 下载和上传 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后台任务 后台 ...

  6. 重新想象 Windows 8 Store Apps (68) - 后台任务: 控制通道(ControlChannel)

    [源码下载] 重新想象 Windows 8 Store Apps (68) - 后台任务: 控制通道(ControlChannel) 作者:webabcd 介绍重新想象 Windows 8 Store ...

  7. 重新想象 Windows 8 Store Apps (34) - 通知: Toast Demo, Tile Demo, Badge Demo

    [源码下载] 重新想象 Windows 8 Store Apps (34) - 通知: Toast Demo, Tile Demo, Badge Demo 作者:webabcd 介绍重新想象 Wind ...

  8. 重新想象 Windows 8 Store Apps (35) - 通知: Toast 详解

    [源码下载] 重新想象 Windows 8 Store Apps (35) - 通知: Toast 详解 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 通知 Toa ...

  9. 重新想象 Windows 8 Store Apps (36) - 通知: Tile 详解

    [源码下载] 重新想象 Windows 8 Store Apps (36) - 通知: Tile 详解 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 通知 Tile ...

随机推荐

  1. Android 模拟器检测

    参考链接:https://github.com/MindMac/HideAndroidEmulator 从多个方面识别模拟器1.用户习惯:联系人数量.短信数量.相册里面照片数量.安装的应用2.从IME ...

  2. 《objective-c基础教程》学习笔记(十一)—— 类别

    在编写面向对象程序的时候,我们经常想为现有的类添加一些新的行为.有些时候,我们可以创建这个类的子类.但是,如果我们用到工具集或者类库的时候,无法处理新建的子类.这时,Objective-C就给我们提供 ...

  3. mac安装 配置 ant

    转自:http://blog.sina.com.cn/s/blog_877e9c3c0101qs87.html 1.下载ant 官网下载 http://ant.apache.org/bindownlo ...

  4. android 开发环境

    http://blog.csdn.net/shulianghan/article/details/38023959

  5. 控制反转(Ioc)和依赖注入(DI)

    控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...

  6. 一个基于POP3协议进行邮箱账号验证的类

    最近老陈要针对企业邮箱做一些开发,以对接企业OA神马的,但企业邮箱唯独没有开放账号密码验证功能,很恼火!不得已,翻出早些年的Asp代码改编成了C#类,实现了一个C#下的通过POP3协议进行邮箱账号验证 ...

  7. coreseek 提示 client version is higher than daemon version 解决办法

    安装好coreseek,开启了服务之后,通过 sphinx php扩展去请求数据,提示:client version is higher than daemon version (client is ...

  8. 【cs229-Lecture17】离散与维数灾难

    主要内容: 解决MDP问题的算法: 离散化: 模型MDP的同化型: (model/similator) 拟合值迭代算法: Q函数: 近似政策迭代: 笔记转自:http://blog.csdn.net/ ...

  9. win7激活

    应亲戚要求,装了次win7系统,重新删除分区,格盘,重新划分好分区.完毕.发现系统分区全自动变成动态磁盘.使用win7激活工具时,注意选择使用 小马通用版激活工具. 动态磁盘 稍后解释 小马工具

  10. android小技巧和注意事项

    在listView 或者 gridView 的使用中,通常不仅仅为了展现数据,更多的是操作数据.于是当控件重合在一起时,我们需要添加事件.就会出现一个问题,当点击一个控件和长按这个控件时,常常出现长按 ...