msdevcon.ru#msdevcon. windows phone 8 networking survival kit andy wigley microsoft uk
TRANSCRIPT
msdevcon.ru #msdevcon
Windows Phone 8 Networking Survival KitAndy WigleyMicrosoft UK
Session Objective(s): Use async and await for HTTP programmingMake smart decisions about data transferUse Compression on Windows PhoneStore Files in SkyDriveAccess local services from the Emulator Program Bluetooth applicationsImplement NFC ‘Tap to Share’ features in your apps
Be a Windows Phone Networking Guru!Build Great Windows Phone Networked Applications
Session Objectives And Takeaways
Http Programming with async and await
MICROSOFT CONFIDENTIAL – INTERNAL ONLY
Async Support in WP8 Networking APIsC# 5.0 includes the async and await keywords to ease writing of asynchronous codeIn Windows Store Apps, new Task-based methods exclusively used for networking, not supported on Windows Phone 8HttpClient APIHttpWebRequest.GetResponseAsync()
Workarounds are available:Async with WebClient possible using extension methods Async with HttpWebRequest possible using extension methods or TaskFactory.FromAsync<T>
Networking APIs Platform AvailabilityAPI WP7.1 WP8 W8
System.Net.WebClient
System.Net.HttpWebRequest
System.Net.Http.HttpClient ( NuGet) ( NuGet)
Windows.Web.Syndication.SyndicationClient
Windows.Web.AtomPub.AtomPubClient
ASMX Web Services
WCF Services
OData Services
HTTP Networking without Asyncusing 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")); }
Http Networking with Asyncusing 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(); ... }
Using HttpClient// Following requires HttpClient.Compression NuGet packagevar handler = new AdvancedREI.Net.Http.Compression.CompressedHttpClientHandler();
// Create the HttpClientHttpClient 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 headershttpClient.DefaultRequestHeaders.Add("Accept", "application/json");
// Make the callHttpResponseMessage 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 AsyncAndy Wigley
Make Smart Decisions About Data Transfer
Making Decisions based on Data ConnectionsMobile apps shouldn’t diminish the user experience by trying to send or receive data in the absence of network connectivityMobile apps should be intelligent about performing heavy data transfers only when the appropriate connectivity is available
Use the NetworkInterfaceType object to detect network type and speed Subscribe to the NetworkChange event to detect when the network state changes
12
Network Awareness
NetworkInformation in Windows Phone 8.0• In Microsoft.Phone.Net.NetworkInformation namespace:• Determine the Network Operator:• DeviceNetworkInformation.CellularMobileOperator
• Determine the Network Capabilities:• DeviceNetworkInformation.IsNetworkAvailable• DeviceNetworkInformation.IsCellularDataEnabled• DeviceNetworkInformation.IsCellularDataRoamingEnabled• DeviceNetworkInformation.IsWiFiEnabled
• In Windows.Networking.Connectivity namespace:• Get Information about the current internet connection• NetworkInformation.GetInternetConnectionProfile
Determining the Internet Connection Typeprivate 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; }}
Tips for Network EfficiencyMobile devices are often connected to poor quality network connectionsBest chance of success in network data transfers achieved by:Keep data volumes as small as possibleUse the most compact data serialization available (use JSON instead of XML)Avoid large data transfers
Avoid transferring redundant dataDesign your protocol to only transfer precisely the data you need and no more
DEMO
Wire SerializationAndy Wigley
Wire Serialization Affects Payroll Size• Simple test
case: download 30 data records
• Each record just 12 fields
• Measured bytes to transfer
Wire Serialization Format
Size in Bytes
ODATA XML 73786
ODATA JSON ATOM 34030
JSON ‘Lite’ 15540
JSON ‘Lite’ GZip 8680
Implementing Compression
Implementing Compression
WP8 SDK does not include System.IO.Compression.GZipStreamUse third-party solutions insteadSharpZipLib is a popular C# compression library (http://sharpziplib.com/) – on NuGetSharpCompress is another (http://sharpcompress.codeplex.com/)
GZipWebClient available from NuGetDrop-in replacement for WebClient, but adds support for compressionUses SharpZipLib internally
HttpWebRequest – With Compressionvar 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();
Compression with OData Client Library 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
MICROSOFT CONFIDENTIAL – INTERNAL ONLY
Configuring Dynamic Content Compression in IIS8 - 1Enable Dynamic Content Compression in Turn Windows Features on or off
MICROSOFT CONFIDENTIAL – INTERNAL ONLY
Configuring Dynamic Content Compression in IIS8 - 2In IIS Manager, select the top line – the ServerIn Features View, open Compression in IIS FeaturesCheck Enable Dynamic Content Compression
MICROSOFT CONFIDENTIAL – INTERNAL ONLY
Configuring Dynamic Content Compression in IIS8 - 3In Features View, scroll down to bottom, open Configuration EditorExpand System.WebserverSelect httpCompressionAdd the following new items to the dynamicTypes collection, all with enabled=Trueapplication/atom+xmlapplication/atom+xml;charset=utf8application/jsonapplication/json;odata=verbose
MICROSOFT CONFIDENTIAL – INTERNAL ONLY
Monitoring Traffic with FiddlerConfigure Fiddler as a reverse proxy:Start Fiddler, then on the Tools menu, click Fiddler OptionsOn the Connections tab, check Allow remote computers to connect. Click OK.
On the Rules menu, click Customize Rules…Add the following to the end of the OnBeforeRequest method:
// Re-route connections from remote hosts to port 80 if (oSession.host.toLowerCase() == "yourpc:8888") oSession.host = "yourpc:80"; Replace yourpc with the name of your PC
Open port 8888 in your firewallIn the Windows Phone client app, change the service URL to http://yourPC:8888/... So that the requests are routed via Fiddler.
DEMO
CompressionAndy Wigley
Accessing Local Services from the Emulator
Windows Phone 8 Emulator and localhostIn Windows Phone 7.x, the emulator shared the networking of the Host PCYou could host services on your PC and access them from your code using http://localhost ...
In Windows Phone 8, the emulator is a Virtual machine running under Hyper-VYou cannot access services on your PC using http://localhost ...You must use the correct host name or raw IP address of your host PC in URIs
MICROSOFT CONFIDENTIAL – INTERNAL ONLY
Configuring Sites Running in IIS ExpressSTEP 1: Create Your Website or Web service
Create your website or web service in Visual Studio 2012Run it and it is configured to run in localhost:port
Configuring Sites Running in IIS ExpressSTEP 2: Modify Config to Run on a URI Using Your PC NameRemove your website (don’t delete!) from the Visual Studio 2012 solutionEdit the file C:\Users\yourUsername\Documents\IISExpress\config\applicationhost.config
Find the <sites> sectionFind the entry for the website or service you just createdChange<binding protocol="http" bindingInformation="*:18009:localhost" />to<binding protocol="http" bindingInformation="*:18009:YourPCName" />
Save changesUse ‘Add Existing Website’ to add the website folder back into your solutionRun it and access from your desktop browser – Now it is hosted at YourPCName:18009
Configuring Sites Running in IIS ExpressSTEP 3: Open Port in the Firewall and Register URLFrom a Command Prompt (Run as Administrator), open the port in the Firewall:netsh advfirewall firewall add rule name="IIS Express (non-SSL)" action=allow protocol=TCP dir=in localport=8080
Also run the following at the command prompt:netsh http add urlacl url=http://yourPC:8080/ user=everyone
Substitute yourPC with the host name of your Host PCSubstitute 8080 for the port where your service is running
Useful References:
How to: Specify a Port for the Development Server http://msdn.microsoft.com/en-us/library/ms178109(v=VS.100).aspx
DEMO
Accessing local services from the emulatorAndy Wigley
Bluetooth
Local Communication with WP8Local Communication is new to Windows Phone 8In Windows Phone 7 processes had to communicate using network connectionsThis was difficult because programs had to determine the required IP address
In Windows Phone 8 there are two new local communication methods available:BluetoothCan be used for phone to phone and phone to device communication over a range of up to 10 meters
Near Field Communication (NFC)Can be used for phone to device communication in very close proximity
Bluetooth ScenariosBluetooth is a short range wireless communication technologyNominally the range is up to 10 metres, but this can be reduced by the conditions
Two Bluetooth communication scenarios supported:App to deviceA program running on a Windows Phone can establish a connection to an external device The Windows Phone must be paired with the device
App to appA program running on a Windows Phone can find another application that is offering a service that the device wishes to useIn this situation pairing is not required
The Bluetooth connection is provided to the program in the form of a StreamSocket
App to DeviceAn application running on a Windows Phone 8 device can obtain an enumeration of all the Bluetooth devices that have been paired with the phone
The application can then attempt to make a connection to the required service on that device
The ID_CAP_PROXIMITY and ID_CAP_NETWORKING capabilities must be enabled for the application to make use of the Bluetooth communications to a device
Bluetooth PairingFor App-to-Device scenarios, the device must have been paired with the phoneA device must be made “discoverable” before pairing can take placePairing is normally performed via the settings screen on the device During the pairing the connection is authenticatedThe user may need to enter a key to validate the connectionThis may be a fixed key, as in the case of devices such as headsets, or generated by one device and entered on the other
In an App-to-App Bluetooth connection, one app is looking for another instance of itself on another phoneCan communicate without needing to be paired
Finding Paired devicesThe PeerFinder class can be used to search for paired devices
The search will fail with the exception shown above if Bluetooth is switched off
try{ PeerFinder.AlternateIdentities["Bluetooth:Paired"] = ""; var peers = await PeerFinder.FindAllPeersAsync();}catch (Exception ex){ if ((uint)ex.HResult == 0x8007048F) MessageBox.Show("Bluetooth is switched off");}
App to App communicationApp to App communication allows two programs to interact using Bluetooth to exchange messagesAn application can wait for and respond to messages from another applicationThe PeerFinder class exposes an event which is raised when a communication request is received from another systemThe communication is still performed using a SocketStream that links the two programsThe devices do not need to be paired in order to implement app to app connection
The ID_CAP_PROXIMITY capability must be enabled
Advertising a Bluetooth ServiceAn application can advertise itself as accepting connections by setting the display name for the PeerFinder and then starting to advertise the serviceNote that doing this for a long time may have an adverse effect on battery life
This task can also be used to provide quick access to other settings
// Register for incoming connection requestsPeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;
// Start advertising ourselves so that our peers can find usPeerFinder.DisplayName = "TicTacToe BT";PeerFinder.Start();
Waiting for an Incoming ConnectionAn application can subscribe to the ConnectionRequested eventWhen the event fires the application can then decide whether to accept the requestIt could display a confirmation dialog to the user
This task can also be used to provide quick access to other settings
// Register for incoming connection requestsPeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;
// Start advertising ourselves so that our peers can find usPeerFinder.DisplayName = "TicTacToe BT";PeerFinder.Start();
Responding to a Connection Request
The above method creates a connection to an incoming request from “RobsPhone”It uses the PeerInformation property of the ConnectionRequestedEventArgs to determine who is attempting to connect
This task can also be used to provide quick access to other settings
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 communicationAndy Wigley
NFC
Near Field Communications
NFC provides a connection between devices that are very close together (within 3-4 centimetres)The data is transferred at a rate of up to 424 Kbits/secondIt is assumed that this data transfer is intentional so there is not normally any authentication as suchThe user has positioned their device close to the other device
The phone can connect to an unpowered NFC chip/tag
Using Near Field CommunicationsNFC is best for sending small amounts of data between devices and can be used in a number of different scenarios:Connect devicesInitiate a Bluetooth or WiFi (Infrastructure) connection to your app on another device
Acquire contentRead “smart” posters that contain digital content in an embedded NFC tag
Exchange digital objectsExchange an electronic business card, or vCard.
Using NFC in applications There are two ways that an application can use NFC
Simple transfer of a message from one device to another
An application can subscribe to message events and receive a string message of a particular type
An NFC connection can be used to configure a connection which is implemented using Bluetooth or WiFi
This extends the PeerFinder to allow an application to use NFC to quickly set up a StreamSocket between two devices
Programming NFC Tap To ConnectIn this usage, the PeerFinder class is used to search for other instances of itself on the tapped deviceProximityDevice device = ProximityDevice.GetDefault();
// Make sure NFC is supportedif (device != null){ PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnectionStateChanged;
// Start finding peer apps, while making this app discoverable by peers PeerFinder.Start();}
Finding a Windows 8 Peer App using NFCSet the PeerFinder.AlternateIdentities property to allow connections to the Windows 8 version of your appProximityDevice device = ProximityDevice.GetDefault();
// Make sure NFC is supportedif (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();}
Setting up a StreamSocket using NFCThe event arguments contain a state change messagevoid 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; }}
Using the connectionThe StreamSocket will be created using WiFi or Bluetooth to transfer the dataAn application can configure the networking technologies by setting these properties
They are both set to true by defaultNote that for a successful infrastructure network connection both devices must be connected to the same subnet and be able to directly connect each other
Note that WiFi Direct is not supported on WP8
PeerFinder.AllowBluetooth = true;PeerFinder.AllowInfrastructure = true;
DEMO
NFC ‘Tap to Connect’ and ‘Tap to Share’Andy Wigley
How to Tap and Share an App 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")); } }
Session Objective(s): Use async and await for HTTP programmingBe smart about data transferUse Compression on Windows PhoneAccess local services from the Emulator Program Bluetooth applicationsImplement NFC ‘Tap to Share’ features in your apps
Be a Windows Phone Networking Guru!Build Great Windows Phone Networked Applications
In Review: Session Objectives And Takeaways
© 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.