Steve Spencer's Blog

The blog of Steve Spencer

Azure Websites Slots and Configuration

One of the conundrums we have with deploying sites to test means that there is often a lot of configuration that is needed on a test site that is different to a live site. There is also the time and risk of deploying a new instance into the production sites once testing has completed.

Azure websites has introduced deployments slots which allows you to have multiple deployments and swap between them in a similar way you could do with the production and staging slots in cloud services. Websites has the added advantage that you can have more than two slots and you can call them whatever you want.

One approach we are looking at to ensure consistency with what is deployed is to configure up a number of slots on the website for a variety of uses e.g. Production, Staging, UAT. The issue with having multiple slots is that there are often sets of configurations that are required to ensure that each slot will work with the correct backend. By default all configuration stored in the appsettings in web.config will move with the slot. Details of the exact configuration settings that move with the deployment can be found here (http://azure.microsoft.com/en-gb/documentation/articles/web-sites-staged-publishing/)

For example, in my web.config file I have the following setting

<appSettings>

<add key="about" value="This is the web.config text" />

</appSettings>

This setting can be overridden in the Azure portal(s) and these by default will follow the deployment and not stay with the slot.

image

So in this example the "about" config will be set to "This is Now the Staging slot" and when the staging slot is swapped to be production, the new production configuration will also be "This is Now the Staging slot"

This is not necessarily what you want on production. Websites has a feature, that is currently unsupported by the management portal(s), which allows specific configuration items to become sticky i.e. they stay with the slot. There is a powershell cmdlet which allows individual appsettings to be marked as sticky and remain with the slot regardless of the deployment that is in the slot and they will also remain in the slot when the slots are swapped.

This can be set for both Appsettings and connection strings by running the following commands

Set-AzureWebsite -Name somesite -SlotStickyAppSettingNames @("about", "another_config_key")

Set-AzureWebsite -Name somesite -SlotStickyConnectionStringNames @("a_connection_string", "some_other_connectionstring")

After running the commands the example above will still have the configuration setting above, but once the deployment is swapped from the staging slot to production the configuration will remain on the staging slot.

This approach should now allow us to deploy to a UAT slot with UAT configuration and allow the customer to test, when they are happy we can move the same deployment that has just been tested to the staging slot with production configuration and be tested in isolation to live to ensure that it works. When you are happy that the staging slot is working this can then be swapped out to production.

For a more detailed introduction to slots and configuration see:

http://azure.microsoft.com/en-gb/documentation/articles/web-sites-staged-publishing/

http://blog.amitapple.com/post/2014/11/azure-websites-slots/#.VG22ik1yaAg

Moving an Azure Website to a separate set of Virtual Machines

When an Azure Website is created and is in production it will most likely be running in a Standard or Basic configuration. These are both sets of Virtual Machines and can be shared across your websites. In the old portal you could only scale the group of websites together but the new Azure Management portal now allows you to move your websites on to different virtual machines so that if one site is more heavily loaded than others it can be scaled out separately if required. The set of virtual machines is known as a Web Hosting Plan. If you want to move one or more of your websites to a different set of virtual machines then you will need to create a new web hosting plan for this.

In the new portal click on “Browse” in the left hand bar

image

This brings up the Browse Menu.

image

Select “Web hosting plans”

image

You can see that I only have 1 web hosting plan and it is currently hosting two websites. I would like to move them onto separate virtual machines so that I can scale them out independently.

To do this I need to navigate to the web site I wish to move.

image

The top menu needs to be expanded by clicking the 3 dots on the right of the menu bar. this then displays the web hosting plan button.

image

Clicking this displays the web hosting plan associated with this web site

image

Clicking on the new hosting plan option allows you to create a new plan

image

I’ve selected a standard small instance to host my website.

After clicking OK the new hosting plan will be created and the website moved to it. After a short while you should see that the hosting plan has changed in this website as well.

image

Note: you now have two hosting plans both of which will be a separate billing entity. I am also led to believe that if you move everything off of a hosting plan you will still be charged for it.Hosting plans can be deleted once all the websites have been moved off of it. This is done in the Web hosting plan page. right click on the plan you want to delete and select the Delete option

5 Tips for using Azure Web Jobs

1. Use public on the on main class.In order for web jobs to initialise correctly the main class that contains the web jobs needs to be made public. Once this has been added the individual jobs can then be read and should be visible in the output when running locally.

clip_image001

2. In order to store and view the invocation details for each web job you need to configure AzureWebJobsDashboard in the configure tab of the website you have deployed the web job to. Even if you have configured this in your app.config file.

clip_image003

If this is not configured in the website then you will receive the following error when you try and view the web jobs dashboard

clip_image002

3. Debug using Visual Studio. Once of the nice features of the web jobs SDK is the ability to run and debug the web job locally in Visual Studio. Following the Getting Started guide, you create a console application which you can debug in Visual Studio before deploying it to Azure

4. User TextWriter for debugging. The Azure Web Jobs SDK (see the logging section) provides a mechanism to log out information that can be viewed through the Azure Web jobs dashboard. By adding a TextWriter as an input parameter to your web job method, you can use WriteLine to then output information you wish to log.

5. Make your Blob Triggers more efficient by triggering them using BlobOutput. The mechanism that the BlobInput trigger uses has a 10-20 minute lag before the trigger can fire, but each time BlobOutput is used it triggers a rescan for Blob input.

“There is an optimization where any blob written via a [BlobOutput] (as opposed to being written by some external source) will optimistically check for any matching [BlobInputs],” See How does [BlobInput] work?. Storage Queues and Service Bus topics and Queues are generally processed within seconds so if you can use a queue to trigger a BlobOutput then use this to trigger any subsequent BlobInputs

Azure Service Bus Event Hub Firewall Port

I’m investigating the Azure Service Bus Event Hub using the getting started tutorial and I didn’t seem to be able to receive any data. It turns out that our firewall was blocking an outbound port. After some investigation I found a post which hinted at a port for the on premise service bus. Our IT guys kindly enabled the outbound port 5671 and I now can receive data from the event hub.

For completeness the following site has details of the other firewall ports required for service bus : http://msdn.microsoft.com/en-us/library/ee732535.aspx

Internet of Things (IoT): Gadgeteer and Service Bus

Internet of Things seems to bring together two of my favourite topics: Gadgeteer and Service Bus. Whilst researching IoT I came across an article in MSDN magazine written by Clemens Vasters (http://msdn.microsoft.com/en-us/magazine/jj190807.aspx). This article is from July 2012 and things have moved on a little since then, but the fact that he  has Gadgeteer talking to service bus meant that I had to give it a go myself. The first port of call was the previous article (http://msdn.microsoft.com/en-us/magazine/jj133819.aspx - note the link is wrong in the current article). This explains the architecture that the sample is based upon using service bus topics to send commands to the device and a different topic to allow the device to send data. There is also a provisioning service that allows the devices to be initialised with the correct configuration. this provisioning service also configures up the service bus access control service (ACS) to allow each device to have its own security key. This means you can turn off devices using ACS.

Before you start take a look at the Service Bus Explorer as this is a useful tool when you are trying to diagnose why things aren’t working.

As I’m using a GHI Electronics Fez Spider main board I am using the .Net Micro-Framework 4.2. Upgrading the project to 4.2 had a couple of errors which needed resolving. Firstly, you will need to change GetJoystickPosition to GetPosition; secondly, change ConvertBase.ToBase64String to Convert.ToBase64String. This allowed me to run the project on my Gadgeteer board. However, I kept getting an error whenever I tried to call the provisioning service. I kept getting Bad Request. I immediately assumed that my configuration was wrong but after a bit of searching and then turning WCF tracing on I found that the service could not load the service bus assembly so I removed and the re-added it to solve the problem. As I mention configuration its probably a good idea to say what each of the settings in the provisioning service is used for:

sharedSignature : Go to https://manage.windowsazure.com/ and login. Click on service bus and then select the service bus you are using. on the bottom menu click the Connecting Information button. This will popup a configuration window. there are two keys in here. The first is part of the connectionstring and is under the sas section. Copy the connection string and find the key. This is the sharedSignature for this configuration setting.

servicebusNamespace: This is the name of the service bus as it appears in the management portal.i.e. sb://<servicebusNamespace>.servicebus.windows.net

managementKey: In the same connection information popup where you found the shared signature there is a section at the bottom labelled ACS. the managementkey is the Default Key

Microsoft.ServiceBus.ConnectionString: I used the connection string that appears in the SAS section of the connection information popup.

The other configuration you need to do is to change the url for the provisioning service. This is hard coded on the Gadgeteer board and is located in Program.cs, serverAddress variable in the ServiceBusApp project.

The provisioning service should be ready to go. However, I had problems connecting to the service from the Gadgeteer board as I kept receiving NotSupportedException each time I called GetRequestStream. This was due to an issue with the Ethernet configuration when trying to connect over https. This can be solved by updating the ssl seed using the Fez Config tool (https://www.ghielectronics.com/community/forum/topic?id=13927). This is done by clicking the Deployment (Advanced) button and the clicking Update SSL Seed.

image

Once complete I could then connect to the provisioning service. The provisioning service should only be called once per device and it is up to the device to store its configuration in a persistent store. This did not appear to be working on my device. Some of the settings were being but the topic urls were not. I changed the type from a URI to a string and the persistence then seemed to work and I only went to provision once. Each time the provisioning service is called a new subscription is create and a new access control identity and rule are also created.

With all this fixed I could now send messages, but I could not see them. this was because I didn’t have a subscriber to the topic where the data was published. This is easily resolved by creating one, but it will only receive new messages. Any messages sent before the subscription is created will be lost.

The provisioning service also has a web page that allows you to send commands to each device. It will broadcast a message to all devices by putting a single message into the devices topic and it sets the Broadcast property to be true. During provisioning the subscription that is created has a SQL Filter applied which allows the subscription to only receive messages that are targeted specifically at the device or if they are broadcast. The web page puts a message into the topic to tell the device to set its temperature to a specific value.The device should be listening for messages to its subscription and will act on the command once it is received.

The device never seemed to receive the message even though the Service Bus Explorer showed that the message was waiting in the queue. Whenever we tried to connect to the subscription “Bad Request” was being returned. After investigation is turns out that the sample only ever sets the event topic uri and not the devices topic uri. When we try and retrieve the device commands we are trying to connect to the events topic which is not a subscription. The sample needs modifying in Microsoft.ServiceBus.Micro project in the MessagingClient class. I added an extra Uri to the constructor and modified the CreateReceiveRequest and CreateLockRequest methods to use this Uri.

The final thing I changed was the command that is sent from the web page and how it was received:

The sender code in Default.aspx.cs in the BackEndWebrole Project

deviceSender.Broadcast(new Dictionary<string, object> { { "Temperature", this.TextBox1.Text } }, "SetTemperature");

And the receiver code in Program.cs in the ServiceBusApp project:

switch (commandType)
{
      case "SetTemperature":
      if (cmd.Properties.Contains("Temperature"))
      {
               this.settings.TargetTemperature = double.Parse((string)cmd.Properties["Temperature"]);
               StoreSettings(this.settings);
     }
     break;
}

I now have a Gadgeteer device talking to the service bus with the ability to send data and receive commands. My next steps are to create a webjob to process the event data (see my previous post) and also look into event hubs.

Creating a Simple Workflow with Azure Webjobs and Service Bus

With the announcement of an upgrade to the webjobs service in Microsoft Azure service bus triggers to Topics and Queues were added.

This got me thinking about how they could be used and there are a lot of scenarios where events need to trigger simple actions as well as running things off of a timer. Utilising Service Bus Topics along with a number of filtered subscriptions led me to create a simple workflow using Webjobs and Topics.

Setting up web jobs is fairly easy and the two links at the top of this article will give you a good start to this along with the 3 articles written by Mike Stall (about Blobs, Queues and Tables) (although the syntax has changed with the latest update, but its easy enough to work out the changes)

The first thing to note which I didn’t pick up on straight away was that you need to  make sure that you set up connection strings for the diagnostics to work. I did this in the Configure section of the web site where I was deploying the webjob. I also added it to my app.config file so that I could debug locally in Visual Studio

image

They all point to my Azure Storage account.

The way I set this up was to create a message class that contained the data that I wanted to send between states. This message class would be wrapped in a BrokeredMessage and I would use the properties to determine the state of the message. The message is then added to a Service Bus Topic. By setting properties on the message, I could create a number of subscriptions that had an SqlFilter applied which would allow the subscription to only contain messages of a specific type.

When coding this I created a basic console application and added the following code to the Main method: 

// now create the subscriptions for the states
if (!_namespaceManager.SubscriptionExists(TopicName, TopicName + "start"))
{
    _namespaceManager.CreateSubscription(TopicName, TopicName + "start", 
                      new SqlFilter("State='WorkflowStart'"));
}
if (!_namespaceManager.SubscriptionExists(TopicName, TopicName + "state1"))
{
    _namespaceManager.CreateSubscription(TopicName, TopicName + "state1", 
                      new SqlFilter("State='WorkflowState1'"));
}
if (!_namespaceManager.SubscriptionExists(TopicName, TopicName + "state2"))
{
    _namespaceManager.CreateSubscription(TopicName, TopicName + "state2", 

                      new SqlFilter("State='WorkflowState2'"));
}

This allows me to create Topic triggers for the webjob for specific states as follows:

public static void SimpleWorkflowStart(
   [ServiceBusTrigger(TopicName, TopicName + "start")] BrokeredMessage message, TextWriter log)
{
      log.WriteLine("Workflow Started");
      .
      .
      .
 }

Two things to note with the method above. Firstly, the ServiceBusTrigger requires both the Topic name and the subscription name in order to receive the filtered list of messages. Secondly, by adding the TextWriter you can then send logging information to the dashboard, which is useful when trying to diagnose the webjobs when deployed to Azure.

I then setup a number of other methods for each subscription for each state. This allows me to perform whatever action I wanted to in each state. After carrying out the action I modified the message by changing the state property and then put it back onto the Topic. You can’t use the same brokered message so you either have to copy all the data out of the existing message and create a new one or you can use the Clone method on Brokered message (the easy option Smile).

// copied the old message
 BrokeredMessage newMessage = message.Clone();
// change the state
newMessage.Properties["State"] = "WorkflowState2";
TopicClient tc = TopicClient.CreateFromConnectionString(
               ConfigurationManager.ConnectionStrings["ServiceBus"].ConnectionString, TopicName);
// delay sending the message a little
newMessage.ScheduledEnqueueTimeUtc = DateTime.Now.AddSeconds(10);
// send it
tc.Send(newMessage);

In my example I also added a delay to the Enqueue of the message so that I could see things progressing in order. The enqueue time of the message is the delay before the message appears in the subscription. This could be also be used as a delayed trigger if you needed something done after a specific time interval. I also achieve this by adding the data to a Azure SQL db and then using a scheduled webjob to check the db for expired jobs. I created a separate console application for this which looked for messages that were expired due to a specific start date being older than a certain time, sending an email using SendGrid and then marking the record as complete in the db.

Webjobs made the actions easy to do and with the addition of the service bus triggers allowed me to have a fairly simple code structure to carry our a sequence of simple action (which is often what we need to do) without a heavy overhead of a workflow engine. It also utilised a hosting environment that I was already using.

Proximity Communication with Windows Phone

In my previous post I talked about using NFC to communicate between devices and hopefully gave you an introduction to the capabilities of NFC. This post will cover the Proximity API in more detail and show you how to set up a persistent connection between two Windows Phones which will allow you to communicate without needing to keep tapping phones together to transfer data. Windows Phone and Windows 8 apps can utilise the .NET Proximity APIs to connect together apps without needing to be connected to the same network. Proximity uses BlueTooth or WiFi Direct (Not on Windows Phone 8) to make a persistent connection between the two devices and utilising StreamSockets to communicate between the two devices. The proximity API uses a PeerFinder to browse for proximate devices or to sit and wait for a Tap to occur.

The first scenario is to set your app in a mode where it can accept incoming Tap requests, then set up a connection between the two devices.

The second scenario is to start your app and then browse for other devices that are running your app and which are within range of your device.

Both scenarios use the PeerFinder classes to initiate the communication.

Scenario 1: TAP to send

PeerFinder has a number of static methods and events that allow you to wire up your app to respond to peer requests. In the Tap to send scenario your app needs to wait for a tap to occur and then initiate opening up the communications channel. PeerFinder has an event called TriggeredConnectionStateChanged which is triggered upon a Tap initiation and is fired for each event state change that occurs. Upon successful connection an open socket is returned which can then be used for communication between the two devices. Once the event is wired up the PeerFinder needs to be started. This is required for both scenarios. You will also need to ensure that the Proximity and Network capabilities are added to you app manifest.

// Wire up the event and be notified when a device is tapped
PeerFinder.TriggeredConnectionStateChanged += PeerFinder_TriggeredConnectionStateChanged; 
// Start finding peer apps, while making this app discoverable by peers
PeerFinder.Start();

The event handler is as follows:

<Insert Code>

PeerFinder.TriggeredConnectionStateChanged += PeerFinder_TriggeredConnectionStateChanged;
.
.
.
private void PeerFinder_TriggeredConnectionStateChanged(object sender, 
                                            TriggeredConnectionStateChangedEventArgs args)
{
    switch (args.State)
    {
        case TriggeredConnectState.Listening:
            // Connecting as host
            WriteStatusMessage("Listening");

            break;
        case TriggeredConnectState.PeerFound:
            // Proximity gesture is complete and user can pull their devices away. Remaining work is to 
            // establish the connection using a different transport, like TCP/IP or Bluetooth
            WriteStatusMessage("Peer Found");

            break;
        case TriggeredConnectState.Connecting:
            // Connecting as a client
            WriteStatusMessage("Connecting");
            break;
        case TriggeredConnectState.Completed:
            // Connection completed, retrieve the socket over which to communicate
            if (!StreamSockets.ContainsKey(args.Socket.Information.RemoteHostName.CanonicalName))
            {
                StreamSockets.Add(args.Socket.Information.RemoteHostName.CanonicalName, args.Socket);
                _currentConnectionID = args.Socket.Information.RemoteHostName.CanonicalName; 
            }

            WriteStatusMessage("Connected");

            // start the listener off on a new thread
            _Receivethread = new System.Threading.Thread(new ThreadStart(ReceiveData));
            _Receivethread.Start();

            break;
        case TriggeredConnectState.Canceled:
            WriteStatusMessage("Canceled");

            break;
        case TriggeredConnectState.Failed:
            // Connection was unsuccessful
            WriteStatusMessage("Failed");
            break;
    }

}

The code above covers the whole connection process and the important part is the TriggeredConnectState.Completed state. It is in this state that we are presented with a valid socket and in the case of Windows phone 8 a BlueTooth connection between the two phones has been created with an open StreamSocket to enable the communication. We also setup a thread that listens on the socket for incoming data to allow two way communication to occur. Both apps need to go through this process and setup a mechanism for sending and receiving data. PeerFinder will find all apps with the same id but it is possible to find other apps that are compatible with your application by adding alternate application identities by adding the information to the AlternateIdentities collection. However, when I tried to add an alternate Windows Phone 8 identity, the key "WindowsPhone" was not accepted and it looks like only Windows can be used.

Using this method the connection is established when the Tap is initiated but this can get tedious if you want to connect to a number of devices. In this case Scenario 2 would be better.

Scenario 2: Browser for devices

It is also possible to connect to compatible applications directly without the need to Tap devices together. The act of starting a compatible app will allow the device to be discoverable to other devices running the same app. PeerFinder is again used but this time we need to wire up a different event, ConnectionRequested. This is fired when a device attempts to connect and allows the connection to be made. When ConnectionRequested fires, the connection information of the device trying to connect is passed through with the EventArgs and PeerFinder.ConnectAsync is called. On successful connection then the same methods for sending and listening are used as in scenario 1.

PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;
// Start finding peer apps, while making this app discoverable by peers
PeerFinder.Start();
.
.
.
async void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args)
{
    WriteStatusMessage("ConnectionRequested");

    StreamSocket socket = await PeerFinder.ConnectAsync(pi);
    PeerConnected(socket);
}

We've wired up the app so that it is capable of receiving a connection from a remote device, we now need to initiate the connection.

Again this is done using PeerFinder and the method FindAllPeersAsync. Will return a list of applications that are compatible which can then be connected to individually. Only one Peer connection can be made at any one time so you will need to connect, send data and then disconnect before moving on to the next peer. Iterating through the list of PeerInformation that is passed.

IReadOnlyList<PeerInformation> readOnlyList = await PeerFinder.FindAllPeersAsync();
PeersFound(readOnlyList);
.
.
.
private async void PeersFound( IReadOnlyList<PeerInformation> readOnlyList)
{
    foreach (PeerInformation pi in readOnlyList)
    {
        StreamSocket socket = await PeerFinder.ConnectAsync(pi);
        PeerConnected(socket);
        return;//for now lets just deal with the first connection
    }
            
}

private void PeerConnected(StreamSocket socket)
{
    OnConnectionStatusChanged("Connected");

    // Do send/receive stuff here

}

For a full worked example see here and for more details of messages

You will need to look into the capabilities of each device as some will only connect via BlueTooth and others only using WiFi Direct and you can use the properties of PeerFinder to control which mechanism you would like to use

PeerFinder.AllowBluetooth = true;
PeerFinder.AllowInfrastructure = false; 
PeerFinder.AllowWiFiDirect = false;

The two posts should now give you information about how to connect phone apps together and provide some insight into how you can connect other devices and provide a rich set of functionality to you apps that previously required backend services to communicate.

Introducing NFC and Proximity with Windows Phone

Near Field Communication has been seen demonstrated in two ways. Firstly scanning an NFC enabled card which can be programmed to perform a number of different actions such as take your device to a specific url, transfer contact details, start an app or take you to the store to install the app and a number of other options. Secondly you may have seen people touching devices together to do things. These actions are either done via NFC communications in the same way that a tag works but also communication could be done using the proximity apis to create a personal network between the two devices to allow a richer sharing of data between devices. This post will cover NFC communication and will show you how you can use NFC to communicate data to devices both in a static way or programmatically as part of an app.

The simplest way to use NFC to exchange data Is via a physical NFC tag. These tags can be programmed with a range of information such as redirecting your mobile browser to a web page; sharing contact details or starting or installing an app. Each of these can be programmed using an app like the Nokia NFC Writer app documented here.

An NFC enabled device will automatically try and resolve the NFC tag data but it is also possible to have custom messages within a tag. Each tag has different capabilities and data sizes which can be seen here

The data that can be written to a tag can also be seen here

The common tag protocols are : WindowsUri, WindowsMime & NDEF.

NDEF is the Nfc Data Exchange format and is the Raw message format for NFC. This can be used to create custom messages for exchanging other types of data. Information about NDEF can be found here

What is more interesting though is that your phone is not only a reader of NFC data it can also be a sender of data so that the tap and send scenarios can be easily enabled within apps, providing that your device supports NFC.

The code samples below utilise the .NET Proximity APIs in C# and will show you how to add basic send and receive capability to an application.

Firstly you will need to determine whether the device your app is running on supports proximity. This is done by get hold of the default proximity device using:

ProximityDevice device = ProximityDevice.GetDefault();

If the device returned is null then you do not have NFC enable or your device down not have NFC capabilities. You can check to see if you have NFC on your phone in settings. There should be a section on NFC with a slider to turn NFC on or off. Make sure that it is turned on. You will also need to ensure that the capabilities of your app allows proximity and this is done in the app manifest file (ID_CAP_PROXIMITY)

Once you have your proximity device there are a number of events you can wire up which will get fired when another NFC device arrives whether that’s a static tag or an NFC enabled phone or tablet. These are DeviceArrived and DeviceDeparted and they fire as you would expect when the NFC device is tapped and when it is removed. These two event give you a notification about the arrival or departure but not the actual data. For this you will need to subscribe for messages and set up call backs to receive and process the NFC data. Similarly you can use the DeviceArrived event to allow you to send data to the other device.

To receive data you do not need to handle the DeviceArrived or DeviceDeparted events but you will need to subscribe for the set of messages you wish to receive including custom messages. You can create different handlers for each type of message you wish to receive.

long subscriptionID = device.SubscribeForMessage("Windows.BlackMarbleMessage", messageReceived);

Here I am subscribing to a custom message of type Windows.BlackMarbleMessage which my messageReceived method knows how to process:

private void messageReceived(ProximityDevice sender, ProximityMessage message)
{

    Debug.WriteLine("Received from {0}:'{1}'", sender.DeviceId, message.DataAsString);
    WriteMessageText(message.DataAsString);
}

My messageReceived method just takes the content of the message and displays it on the screen, but in a real life scenario the data could be JSON or XML for example and you process them accordingly.

The standard set of tag protocols is documented here if you want to access the raw NDEF protocol then the codeplex project here can be used

An application cannot determine whether the device arrived is an active device or just a passive tag so if you want to send messages out you need to understand that there may not be a response so make sure that your app is not expecting a response in order to proceed.

Sending data can be achieved by sending a message to the proximity device when you know that a device has arrived, so for this you will need to wire up the DeviceArrived event.

device.DeviceArrived += device_DeviceArrived;

.
.
.


void device_DeviceArrived(ProximityDevice sender)
{
    if (_bSendingMessage)
    {
        if(string.IsNullOrEmpty(_messageToSend))
                _messageToSend = "Hello World";
        sender.PublishMessage("Windows.BlackMarbleMessage", _messageToSend);
                
    }
            
}

This example is part of a phone app which needs to check a check box and enter some data in a text box in order to send data. Sending data is done through the PublishMessage, PublishBinaryMessage or PublishUriMessage methods. If you use PublishMessage or PublishBinaryMessage then you will need to add a string identifier for the message type which needs to match the message type that the receiver has subscribed to. In my example this is "Windows.BlackMarbleMessage".

Let's assume that we've installed this app onto two Windows 8 phones, one of the phones has the send message check box checked and has some data in the data check box. The two phones are Tapped together. Both apps will receive the DeviceArrived event and the device_DeviceArrived method is called on both apps. The phone with the send message check box checked will then send a Windows.BlackMarble message containing the data in the data text box to the other phone. The other phone then receives the message in its messageReceived method and will display it on the screen.

This is a basic example but it shows how you can send through simple message data and to add Tap functionality to you apps. This should work across devices and operating systems as the communication is through NFC (although you will need an app that understands your messages if you are sending custom messages).

NFC and proximity can be used to set up a longer running connection between two devices with or without tapping to initiate. There will be a follow on post that covers this shortly.

Windows Store App Notifications, the Notification Hub and Background tasks

This article aims to talk about Windows Store Notifications and the Windows Azure Notifications Hub and it will attempt to collate the various articles in a single place to help you build notifications into your app.

In order for you to get an understanding of Windows notifications look at the following article

Introduction to Push Notifications - http://msdn.microsoft.com/en-us/library/windows/apps/hh913756.aspx. this provides a good overview of how push notifications work. To summarise the important bits.

1. Your store app needs to register with the Windows Notification Service to retrieve a unique URI for your instance of the app. Ideally you do this each time the app starts.

2. If the URI has changed then you need to notify your service that there is a new URI. Note: This URI expires every 30 days so your app needs to notify your service that this has been changed.

3. Your service sends notifications to this unique URI

You may have noticed above that I mentioned “Your service”. This is a critical piece of the notification mechanism and there are a number of ways to build this service. If you are not comfortable building backend services or you want something up and running quickly then mobile services might be the way to go for you. Here’s a tutorial that gets you started with mobile services http://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started/

If, like me, you already have a source of data and a service then you will probably want to wire in notifications into your existing service. depending upon how many devices you have using your app may dictate the method that you get the notifications onto the users device. there are a number of options:

  1. Local updates
  2. Push Notifications
  3. Periodic Notifications

Local updates require the creation of a background task that Windows runs periodically that calls into your data service, retrieves the data to put on the tiles and sends out tile notifications using the Windows Store app SDK

Updating live tiles from a background task - http://msdn.microsoft.com/en-us/library/windows/apps/jj991805.aspx. Provides a tutorial on building a background task for your Windows Store App. this tutorial is for timer tasks but it can easily be used for push notification tasks. The bits that are likely to change are the details of the run method, the task registration and the package manifest.

Two more important links that you will require when you are dealing with notifications:

Tile template catalogue http://msdn.microsoft.com/en-us/library/windows/apps/hh761491.aspx

Toast template catalogue http://msdn.microsoft.com/en-us/library/windows/apps/hh761494.aspx

These two catalogues are important as they provide you with details of the xml you need for each type of notifications

Push notifications are sent through the Windows Notification Service to your device.

You can send notifications to your device from your service by creating a notification and sending it to each of the devices registered to your service via the Windows Notification Service.

If you have a large number of devices running your app then you will probably want to use the Windows Azure Notification Hub. This is the simplest way to manage notifications to your application as the notification hub handles scaling, managing of the device registration and also iterating around each device to send the notifications out. The Notification hub will also allow you to send notifications to Windows Phone, Apple and Android devices. To get started with the notification hubs follow this tutorial:http://www.windowsazure.com/en-us/manage/services/notification-hubs/getting-started-windows-dotnet/

The nice feature of the notification hub is that is makes the code needed to send notifications simple.

 

NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<your notification hub connection string>", "<your hub name>");

 

var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">Hello from a .NET App!</text></binding></visual></toast>";

 

await hub.SendWindowsNativeNotificationAsync(toast);

Compare this to the code to send the notification without the hub:

 

byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);

 

 

HttpWebRequest request = HttpWebRequest.Create(uri) asHttpWebRequest;

request.Method =

"POST";

request.Headers.Add(

"X-WNS-Type", notificationType);

request.ContentType = contentType;

request.Headers.Add(

"Authorization", String.Format("Bearer {0}", accessToken.AccessToken));

 

 

using (Stream requestStream = request.GetRequestStream())

requestStream.Write(contentInBytes, 0, contentInBytes.Length);

 

 

In addition you will need to retrieve the list of devices that are registered for push notifications and iterate around the list to send this to each device. You will also require a service that receives the registrations and stores them in a data store. You need to manage the scalability of these services. On the down side the notification hub is charged per message which means the more often you send notifications the greater the costs where as hosting a service is load based and the notifications will be sent out slower as the number of devices increases but this would generally be a lower cost. If you also take into account that you will need to send out notifications for each tile size and that will increase the activity count on the notification hub for each tile size (currently 3).

[Update: You can send out a single notification for all tile sizes rather than 3 separate notifications by adding a binding for each tile size in your xml see http://msdn.microsoft.com/en-us/library/windows/apps/hh465439.aspx for more details]

It is possible to send custom notifications to your app which can be received directly in the app or by using a background task. These are called Raw notifications. In order to receive raw notifications in a background task your app needs to be configured to display on the start screen. However Raw Notifications can be received in your app whilst it is running when it is not configured to display on the start screen. A Raw Notification is a block of data up to 5KB in size and can be anything you want.

The following code will send a raw notifications using the notifications hub:

 

string rawNotification = prepareRAWPayload();

 

Notification notification = new Microsoft.ServiceBus.Notifications.WindowsNotification(rawNotification);

notification.Headers.Add(

"X-WNS-Cache-Policy", "cache");

notification.Headers.Add(

"X-WNS-Type", "wns/raw");

notification.ContentType =

"application/octet-stream";

 

 

var outcome = await hub.SendNotificationAsync(notification);

In order to receive Raw Notifications in your app you need to add an event to the channel you retrieve from the Windows Notification Service:

 

var channel = awaitPushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

 

channel.PushNotificationReceived += channel_PushNotificationReceived;

 

And then handle the notification received:

 

privatevoid channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)

{

 

switch (args.NotificationType)

{

 

    casePushNotificationType.Raw:

 

        ReceiveNotification(args.RawNotification.Content);

 

    break;

}

}

 

Note: the content of the notification is the block of data that you sent out.

Sample background task for Raw Notifications is here: http://msdn.microsoft.com/en-us/library/windows/apps/jj709906.aspx

Guidelines for Raw Notifications can be found here: http://msdn.microsoft.com/en-us/library/windows/apps/hh761463.aspx

Periodic notifications also require a service but the application periodically calls into a service to retrieve the tile notifications without needing to process the source data and then create the notifications locally. details about how to use periodic notifications can be found here: http://msdn.microsoft.com/en-US/library/windows/apps/jj150587

In summary Windows Store application notifications can be send to the app in a variety of ways and the mechanism you choose will depend upon how quick and how many notifications are required. Push notifications allow notifications to be sent whenever they are ready to send. Periodic and Local updates are pull notifications and require a service to be available to pull the data from. All of these will require some sort of service and all have an associated costs. The notifications hub is a useful tool to assist with notifications and it can be useful to manage the device connections as well as sending out notifications to multiple device type. It does however come at a cost and you need to work out whether it is a cost effective mechanism for your solution.

Gadgeteer, Signal R, WebAPI & Windows Azure

After a good night in Hereford at the Smart Devs User Group and my presentation at DDDNorth

Here are the links from my presentation and some from questions asked:

Gadgeteer: http://www.netmf.com/gadgeteer/

Signal-R: http://www.asp.net/signalr/

Web API: http://www.asp.net/web-api

The Signal-R chat example can be found at: http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr

Windows Azure Pricing Calculator : http://www.windowsazure.com/en-us/pricing/calculator/?scenario=full

Signal-R Scaleout using Service bus, SQL Server or Redis: http://www.asp.net/signalr/overview/performance-and-scaling/scaleout-in-signalr

The Windows Azure Training Kit: http://www.windowsazure.com/en-us/develop/net/other-resources/training-kit/

Gadgeteer Modules: http://proto-pic.co.uk/categories/development-boards/net.html

Fex Spider Starter Kit: http://proto-pic.co.uk/fez-spider-starter-kit/

 

In addition to these links I have more from my presentation at the DareDevs user group in Warrington

It is possible to drive a larger display from Gadgeteer using a VGA adapter. You use this the same way that the Display-T35 works using the SimpleGraphics interface for example.

VB eBook - Learn to Program with Visual Basic and Gadgeteer

Fez Cerberus Tinker Kit: https://www.ghielectronics.com/catalog/product/455