msdevcon.ru
#msdevcon
Windows Phone 8 Networking
Survival Kit
Andy Wigley
Microsoft UK
Http Programming with async and await
C# 5.0 includes the async and await keywords to ease
writing of asynchronous code
In Windows Store Apps, new Task-based methods
exclusively used for networking, not supported on
Windows Phone 8
Workarounds are available:
API
WP7.1
WP8
W8
System.Net.WebClient



System.Net.HttpWebRequest



 ( NuGet)
 ( NuGet)

Windows.Web.Syndication.SyndicationClient



Windows.Web.AtomPub.AtomPubClient



ASMX Web Services



WCF Services



OData Services



System.Net.Http.HttpClient
using System.Net;
...
WebClient client;
public MainPage()
{
...
client = new WebClient();
client.DownloadStringCompleted += client_DownloadStringCompleted;
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
this.downloadedText = e.Result;
}
private void loadButton_Click(object sender, RoutedEventArgs e)
{
client.DownloadStringAsync(new Uri("http://MyServer/ServicesApplication/rssdump.xml"));
}
using System.Net;
using System.Threading.Tasks;
...
private async void LoadWithWebClient()
{
var client = new WebClient();
string response = await client.DownloadStringTaskAsync(
new Uri("http://MyServer/ServicesApplication/rssdump.xml"));
this.downloadedText = response;
}
private async void LoadWithHttpWebRequest()
{
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("http://services.odata.org/Northwind/Northwind.svc/Suppliers");
request.Method = HttpMethod.Get;
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
...
}
// Following requires HttpClient.Compression NuGet package
var handler = new AdvancedREI.Net.Http.Compression.CompressedHttpClientHandler();
// Create the HttpClient
HttpClient httpClient = new HttpClient(handler);
// To use without compression support (but why do that?), use default HttpClient constructor
// without the compression handler: HttpClient httpClient = new HttpClient();
// Optionally, define HTTP headers
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
// Make the call
HttpResponseMessage response = await httpClient.GetAsync(
"http://services.odata.org/Northwind/Northwind.svc/Suppliers");
response.EnsureSuccessStatusCode(); // Throws exception if bad HTTP status code
string responseBodyAsText = await response.Content.ReadAsStringAsync();
DEMO
HTTP Networking using Async
Andy Wigley
Make Smart Decisions About Data Transfer
Making Decisions based on Data Connections
Use the NetworkInterfaceType object to detect
network type and speed
Subscribe to the NetworkChange event to detect
when the network state changes
12
private const int IANA_INTERFACE_TYPE_OTHER = 1;
private const int IANA_INTERFACE_TYPE_ETHERNET = 6;
private const int IANA_INTERFACE_TYPE_PPP = 23;
private const int IANA_INTERFACE_TYPE_WIFI = 71;
...
string network = string.Empty;
// Get current Internet Connection Profile.
ConnectionProfile internetConnectionProfile =
Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
if (internetConnectionProfile != null) // if ‘null’, we are offline.
{
switch (internetConnectionProfile.NetworkAdapter.IanaInterfaceType)
{
case IANA_INTERFACE_TYPE_OTHER:
cost += "Network: Other"; break;
case IANA_INTERFACE_TYPE_ETHERNET:
cost += "Network: Ethernet"; break;
case IANA_INTERFACE_TYPE_WIFI:
cost += "Network: Wifi\r\n"; break;
default:
cost += "Network: Unknown\r\n"; break;
}
}
Mobile devices are often connected to poor quality
network connections
Best chance of success in network data transfers
achieved by:
Avoid transferring redundant data
Design your protocol to only transfer precisely the
data you need and no more
DEMO
Wire Serialization
Andy Wigley
Wire Serialization Format
Size in Bytes
ODATA XML
73786
ODATA JSON ATOM
34030
JSON ‘Lite’
15540
JSON ‘Lite’ GZip
8680
Implementing Compression
http://sharpziplib.com/
http://sharpcompress.codeplex.com/
var request =
HttpWebRequest.Create("http://yourPC:15500/NorthwindDataService.svc/Suppliers")
as HttpWebRequest;
request.Accept = "application/json";
request.Method = HttpMethod.Get;
request.Headers["Accept-Encoding"] = "gzip";
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
// Read the response into a Stream object.
System.IO.Stream responseStream = response.GetResponseStream();
string data;
var stream = new GZipInputStream(response.GetResponseStream());
using (var reader = new System.IO.StreamReader(stream))
{
data = reader.ReadToEnd();
}
responseStream.Close();
private void EnableGZipResponses(DataServiceContext ctx)
{
ctx.WritingRequest += new EventHandler<ReadingWritingHttpMessageEventArgs>(
(_, args) =>
{
args.Headers["Accept-Encoding"] = "gzip";
} );
ctx.ReadingResponse += new EventHandler<ReadingWritingHttpMessageEventArgs>(
(_, args) =>
{
if (args.Headers.ContainsKey("Content-Encoding") &&
args.Headers["Content-Encoding"].Contains("gzip"))
{
args.Content = new GZipStream(args.Content);
}
} );
}
Reference: http://blogs.msdn.com/b/astoriateam/archive/2011/10/04/odata-compression-in-windows-phone-7-5-mango.aspx
if (oSession.host.toLowerCase() == "yourpc:8888")
oSession.host = "yourpc:80";
http://yourPC:8888/
DEMO
Compression
Andy Wigley
Accessing Local Services from the Emulator
http://localhost
http://localhost
C:\Users\yourUsername\Documents\IISExpress\config\applicationhost.config
<sites>
<binding protocol="http" bindingInformation="*:18009:localhost" />
<binding protocol="http" bindingInformation="*:18009:YourPCName" />
YourPCName:18009
netsh advfirewall firewall add rule name="IIS Express (non-SSL)" action=allow
protocol=TCP dir=in localport=8080
yourPC
8080
http://msdn.microsoft.com/en-us/library/ms178109(v=VS.100).aspx
DEMO
Accessing local services from the
emulator
Andy Wigley
Bluetooth
Bluetooth
Near Field Communication (NFC)
App to device
App to app
try
{
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var peers = await PeerFinder.FindAllPeersAsync();
}
catch (Exception ex)
{
if ((uint)ex.HResult == 0x8007048F)
MessageBox.Show("Bluetooth is switched off");
}
// Register for incoming connection requests
PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;
// Start advertising ourselves so that our peers can find us
PeerFinder.DisplayName = "TicTacToe BT";
PeerFinder.Start();
// Register for incoming connection requests
PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;
// Start advertising ourselves so that our peers can find us
PeerFinder.DisplayName = "TicTacToe BT";
PeerFinder.Start();
StreamSocket socket;
async void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
{
if ( args.PeerInformation.DisplayName == "RobsPhone" )
{
socket = await PeerFinder.ConnectAsync(args.PeerInformation);
PeerFinder.Stop();
}
}
DEMO
Bluetooth communication
Andy Wigley
NFC
Connect devices
Acquire content
Exchange digital objects
ProximityDevice device = ProximityDevice.GetDefault();
// Make sure NFC is supported
if (device != null)
{
PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnectionStateChanged;
// Start finding peer apps, while making this app discoverable by peers
PeerFinder.Start();
}
ProximityDevice device = ProximityDevice.GetDefault();
// Make sure NFC is supported
if (device != null)
{
PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnStateChanged;
// Include the Windows 8 version of our app as possible peer
PeerFinder.AlternateIdentities.Add("Windows", "my Win8 appID");
// Start finding peer apps, while making this app discoverable by peers
PeerFinder.Start();
}
void OnTriggeredConnStateChanged(object sender, TriggeredConnectionStateChangedEventArgs args)
{
switch (args.State)
{
case TriggeredConnectState.Listening: // Connecting as host
break;
case TriggeredConnectState.PeerFound: // Proximity gesture is complete – setting up link
break;
case TriggeredConnectState.Connecting: // Connecting as a client
break;
case TriggeredConnectState.Completed: // Connection completed, get the socket
streamSocket = args.Socket;
break;
case TriggeredConnectState.Canceled:
// ongoing connection cancelled
break;
case TriggeredConnectState.Failed:
// Connection was unsuccessful
break;
}
}
PeerFinder.AllowBluetooth = true;
PeerFinder.AllowInfrastructure = true;
DEMO
NFC ‘Tap to Connect’
and ‘Tap to Share’
Andy Wigley
Windows.Networking.Proximity.ProximityDevice proximityDevice;
long publishedMessageId = -1;
private void PublishUriButton_Click(object sender, RoutedEventArgs e)
{
if (proximityDevice == null) proximityDevice = ProximityDevice.GetDefault();
// Make sure NFC is supported
if (proximityDevice != null) {
// Stop publishing the current message.
if (publishedMessageId != -1) {
proximityDevice.StopPublishingMessage(publishedMessageId);
}
// Publish the new one
publishedMessageId = proximityDevice.PublishUriMessage(
new Uri("zune:navigate?appid=351decc7-ea2f-e011-854c-00237de2db9e"));
}
}
Контакты
Andy Wigley
Microsoft
andy.wigley@microsoft.com & @andy_wigley
andywigley.com
© 2013 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of
Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.