Develop Apps > Communications > Networking and web services
Networking basics
App的联网能力是受管控的,有三种能力声明:
- internetClient,可以访问公共网络
- internetClientServer,可以作为公共网络的服务器
- privateNetworkClientServer,可以在私有网络(家、公司)等作为客户端和服务器
一些相关的,但是不常用的能力声明:
- enterpriseAuthentication,允许应用使用域账号访问受限资源。有此能力的应用可以在域管控的网络上代表用户访问资源。
- proximity,在近场通信使用
- sharedUserCertificates,允许访问用户的软件或者硬件证书(比如smart card上的证书)
当应用处于后台时,必须注册后台任务才能处理进来的网络数据。历史上使用Control Channel Trigger作为后台任务的触发。Win10提供了一些额外的机制,比如push-enabled stream sockets提供的socket broker以及socket activity trigger。
如果你的应用使用了DatagramSocket, StreamSocket, 或者StreamSocketListener。那么在进入后台的时候可以把socket转交给系统的socket broker处理。当有数据进来的时候,socket broker会触发(比如使用SocketActivityTrigger)相应的后台任务,这时候应用可以接过socket来处理其中的数据。
socket broker在很多场景可以替代Control Channel Triggers。socket broker有很多好处,比如节省系统资源,可以侦听TCP,可以在Connected Standby模式工作。但是也有缺点,比如不能在Lock Screen应用中使用。
选择相应的网络触发器:
- 如果使用 IXMLHTTPRequest2、System.Net.Http.HttpClient 或者System.Net.Http.HttpClientHandler,,必须使用Control Channel Trigger
- 如果使用push-enabled StreamSockets,可以使用Control Channel Trigger,但是最好使用SocketActivityTrigger。
Network communications in the background
StreamSocket可以配置使用SSL/TLS。但是通过StreamSocketListener创建的StreamSocket无法主动配置SSL/TLS,因为这时候连接已经建立起来了。
配置SSL/TLS有两种办法:
- ConnectAsync ,一开始就使用SSL/TLS
- UpgradeToSslAsync,一开始不适用,但是后来升级到SSL/TLS。
StreamSocket的SocketProtectionLevel需要通信双方共同决定,所以实际生效的会比预设的要低。也就是说StreamSocketinformation.ProtectionLevel 反映的不是真实使用的保护级别。
例子:
和普通的socket一样,WebSocket(StreamWebSocket和MessageWebSocket)也可以使用SSL/TLS来加密。具体的例子参考How to secure WebSocket connections with TLS/SSL
Websocket使用了Sec-WebSocket-Protocol来指明协议信息。这个会在StreamWebSocketInformation.Protocol和MessageWebSocketInformation.Protocol 部属中体现。
StreamSocket支持SSL/TLS验证。但是有时候,应用自身也要使用TLS向服务端做验证。在Win10,可以通过StreamSocket.Control来提供客户端证书。也就是当服务端要求的时候,Windows会把StreamSocket.Control的证书提供给服务端。示例如下:
var socket = new StreamSocket();
Windows.Security.Cryptography.Certificates.Certificate certificate = await GetClientCert();
socket.Control.ClientCertificate = certificate;
await socket.ConnectAsync(destination, SocketProtectionLevel.Tls12);
通过将PasswordCredential设置到通信协议的部属中,可以对该通信协议提供验证信息,如下所示:
- WebSockets
- MessageWebSocketControl.ServerCredential
- MessageWebSocketControl.ProxyCredential
- StreamWebSocketControl.ServerCredential
- StreamWebSocketControl.ProxyCredential
- Background Transfer
- BackgroundDownloader.ServerCredential
- BackgroundDownloader.ProxyCredential
- BackgroundUploader.ServerCredential
- BackgroundUploader.ProxyCredential
- Syndication
- SyndicationClient(PasswordCredential)
- SyndicationClient.ServerCredential
- SyndicationClient.ProxyCredential
- AtomPub
- AtomPubClient(PasswordCredential)
- AtomPubClient.ServerCredential
- AtomPubClient.ProxyCredential
在网络通信中,出现异常是常见的事情。代码必须要准备好处理这些异常。错误通常用HRESULT表示。在Winerror.h
中,包含了一个HRESULT可能值的大列表。处理通信的API提供了一些额外的帮助用来处理HRESULT。更多参考Networking API Improvements in Windows 10。
HttpClient
- Windows.Web.Http
- Windows.Web.Http.Headers
- Windows.Web.Http.Filters
这三个命名空间中runtimeclass用来支持UWP对HTTP的处理,包括的功能如下:
- 支持 GET, PUT, POST以及DELETE
- 支持常见验证配置和模式
- 可以访问SSL细节
- 可以包含自定义的filter
- 可以操纵cookies
- 提供异步操作的进度条信息
HttpClient对应的请求和回复为:
- HttpRequestMessage
- HttpRespsonseMessage
上面消息的内容在RFC 2616中定义。
Windows.Web.Http抽象出来的http内容包括http的body、headers以及cookies。http内容可以与一个HTTP请求或者HTTP回复关联。
Windows.Web.Http包括下面工具:
- HttpBufferContent,http内容作为buffer
- HttpFormUrlEncodedContent,一个包括键值对的集合,以application/x-www-form-urlencoded MIME方式编码
- HttpMultipartContent,以multipart/* MIME类型组织的内容
- HttpMultipartFormDataContent,内容以multipart/form-data MIME方式组织
- HttpStreamContent,以流的方式组织内容,这是HTTP GET和POST内部使用的类型
- HttpStringContent,以字符串方式组织内容
- IHttpContent,接口,可供开发者提供自己的内容组织方式
Windows.Web.Http.Headers 所包含的类型可以用来创建HTTP头以及cookies,创建出来的对象通常作为HttpRequestMessage和HttpResponse对象的部属.
代码示例:
// Send the GET request.
httpResponseMessage = httpClient.GetAsync(requestUri).get();
httpResponseMessage.EnsureSuccessStatusCode();
httpResponseBody = httpResponseMessage.Content().ReadAsStringAsync().get();
POST binary data over HTTP阐述如何发送二进制数据。
POST JSON data over HTTP阐述如何发送JSON数据。
对于错误的URI,WinRT会抛出一个异常。在C++中,这个异常在创建Windows.Foundation.Uri时候抛出。
对于大部分参数错误,HRESULT返回E_INVALIDARG。对于一些不支持的函数调用,返回的是E_ILLEGAL_METHOD_CALL。
(本篇完)