Using hints inside text fields instead of labels


The following code example demonstrates replacing labels with hints that appear as temporary values within text fields; akin to placeholder attribute in HTML5.

A custom attribute called data-hint-value contains the hint value to which a text field gets initialized. That value represents what typically would be the value of a label associated with the text field. It is cleared when the text field receives focus, and filled with hint value if text field is empty on blur.

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
    <link rel="shortcut icon" href="favicon.ico">
    <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
</head>
<body>
    <input id="name" type="text" data-hint-value="your name" />
    <script type="text/javascript">

        function setAllTextToHint() {
            $(":text").each(function (index) {
                hint = $(this).attr("data-hint-value");
                if (hint) $(this).val(hint);
            });
        }

        function isTextValueValid(id) {
            var ret = false;
            $(":text").each(function (index) {
                thisId = $(this).attr("id");
                if (thisId == id) {
                    hint = $(this).attr("data-hint-value");
                    value = $(this).val();
                    if (value == hint || value == "") {
                        alert("Please specify " + hint);
                        $(this).val(hint);
                        $(this).focus();
                        return;
                    } else {
                        ret = true;
                        return;
                    }
                }
            });
            return ret;
        }

        $(":text").focus(function () {
            hint = $(this).attr("data-hint-value");
            if ($(this).val() == hint)
                $(this).val("");
        });

        $(":text").blur(function () {
            hint = $(this).attr("data-hint-value");
            if ($(this).val() == "") {
                $(this).val(hint);
            }
        });
    </script>

setAllTextToHint is a helper function that sets all text fields to their hint values. isTextValueValid may be used to check whether a text field contains some value, and alerts the user when it does not. Tweak these as you see fit.

WebSockets with WCF


This post demonstrates an elementary chat service constructed using WCF and WebSockets. A custom binding that leverages WebSocket support in httpTransport is used. JSON is serialized and deserialized using byteStreamMessageEncoding encoding. Use httpsTransport for secure transport.

Service interface

The service interface is used to receive connection requests and messages from clients. It has only one method, as shown below.

using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading.Tasks;

namespace ChatService
{
    [ServiceContract(CallbackContract = typeof(IChatServiceCallback))]
    interface IChatService
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        Task SendMessage(Message message);
    }
}

Callback interface

The callback interface is used to send messages back to the clients.

using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading.Tasks;

namespace ChatService
{
    [ServiceContract]
    interface IChatServiceCallback
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        Task ReceiveMessage(Message message);
    }
}

Service implementation

The service implementation receives messages from clients, and fires them off to other clients, using their respective callback interface. Messages are sent to clients who have sent messages to a chat room, and are still connected.

using System;
using System.Collections.Concurrent;
using System.IO;
using System.Net.WebSockets;
using System.Runtime.Serialization.Json;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading.Tasks;

namespace ChatService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class ChatServiceImplementation : IChatService
    {
        static ConcurrentDictionary<string, ConcurrentDictionary<string, Chatter>> rooms = 
            new ConcurrentDictionary<string, ConcurrentDictionary<string, Chatter>>();

        public async Task SendMessage(Message message)
        {
            if (message.IsEmpty) return;

            byte[] body = message.GetBody<byte[]>();
            MemoryStream stream = new MemoryStream(body);
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Chatter));
            Chatter chatter = (Chatter)ser.ReadObject(stream);
            IChatServiceCallback callback = OperationContext.Current.GetCallbackChannel<IChatServiceCallback>();
            chatter.Callback = callback;

            IChannel channel = (IChannel)callback;
            channel.Faulted += channel_Faulted;
            channel.Closed += channel_Closed;

            ConcurrentDictionary<string, Chatter> room;
            if (!rooms.TryGetValue(chatter.Room, out room))
            {
                room = new ConcurrentDictionary<string, Chatter>();
                rooms.TryAdd(chatter.Room, room);
            }
            Chatter existingChatter;
            if (!room.TryGetValue(chatter.Nickname, out existingChatter))
            {
                room.TryAdd(chatter.Nickname, chatter);
            }
            else if (existingChatter.Callback != chatter.Callback)
            {
                existingChatter.Callback = chatter.Callback;
            }
            foreach (Chatter c in room.Values)
            {
                if (((IChannel)c.Callback).State == CommunicationState.Opened)
                    await c.Callback.ReceiveMessage(CreateMessage(body));
            }
        }

        private void channel_Closed(object sender, EventArgs e)
        {
            // Clean up
        }

        private void channel_Faulted(object sender, EventArgs e)
        {
            // Clean up
        }

        private Message CreateMessage(byte[] message)
        {
            Message channelMessage = ByteStreamMessage.CreateMessage(new ArraySegment<byte>(message));

            channelMessage.Properties["WebSocketMessageProperty"] =
                new WebSocketMessageProperty { MessageType = WebSocketMessageType.Text };

            return channelMessage;
        }
    }
}

Here’s the Chatter class, used to store state.

using System.Runtime.Serialization;

namespace ChatService
{
    [DataContract()]
    class Chatter : IExtensibleDataObject
    {
        [DataMember(Name = "nickname", IsRequired = true)]
        public string Nickname { get; set; }
        [DataMember(Name = "room", IsRequired = true)]
        public string Room { get; set; }
        [DataMember(Name = "message", IsRequired = true)]
        public string Message { get; set; }
        public IChatServiceCallback Callback { get; set; }

        public ExtensionDataObject ExtensionData { get; set; }
    }
}

App.config

App.config below creates a customBinding and associates it with the chat service.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="webSocketHttpBinding">
          <byteStreamMessageEncoding/>
          <httpTransport>
            <webSocketSettings transportUsage="Always" createNotificationOnConnection="true"/>
          </httpTransport>
        </binding>
      </customBinding>
    </bindings>
    <services>
      <service name="ChatService.ChatServiceImplementation">
        <endpoint address="http://localhost:8004/chatservice" binding="customBinding" bindingConfiguration="webSocketHttpBinding" contract="ChatService.IChatService"/>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

Self hosted console app

A console app that hosts the service is shown below.

using System;
using System.ServiceModel;

namespace ChatServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(ChatService.ChatServiceImplementation));
            host.Open();

            Console.WriteLine("Hit Enter to quit.");
            Console.ReadLine();
        }
    }
}

Chat web page

The following web page uses jQuery and WebSocket to send/receive messages to/from chat rooms.

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Chat</title>
    <script type="text/javascript"
            src="https://code.jquery.com/jquery-2.1.4.min.js">
    </script>
</head>
<body>
    <form>
        Nickname <br/>
        <input id="nickname" type="text" value="nickname" /><br/>
        Room 

        <input id="room" type="text" value="room" /><br/>
        Message 

        <input id="message" type="text" value="message" /><br/>
        <input id="send" type="button" value="Send" />
    </form>

    <p>
        Messages
        <div id="messages">

        </div>
    </p>
    <img src="image/HTML5_Logo_64.png" />

    <script type="text/javascript">
        var url = 'ws://localhost:8004/chatservice'; // base url
        var connection = null;
        $(document).ready(documentReady);
        function documentReady() {
            $("#send").click(sendClick);
        }
        function sendClick() {
            if (connection == null) {
                connection = new WebSocket(url);
            } else {
                sendMessage();
                return;
            }
            connection.onopen = sendMessage;
            connection.onmessage = receiveMessage;
            connection.onerror = function (e) {
                alert('error ' + e);
                connection = null;
            };
        }
        
        function sendMessage() {
            var chatter = new Object();
            chatter.nickname = $('#nickname').val();
            chatter.room = $('#room').val();
            chatter.message = $('#message').val();
            connection.send(JSON.stringify(chatter));
        }
        function receiveMessage(e) {
            var chatter = JSON.parse(e.data);
            var message = chatter.nickname + '@' + chatter.room + ' said ' + chatter.message + '<br/>';
            $('#messages').prepend(message);
        }
    </script></body>
</html>

Testing

Open the HTML file in a modern web browser, and you’ll see the chat page. Open the same page in additional tabs. Once you send a message to one or more chat rooms in a tab, messages posted from other tabs using different nicknames to the same chat rooms, should appear in the Messages area in reverse chronological order.

One really pesky problem is the following exception you get, when you try to send the same Message instance to multiple callbacks

A property with the name 'TransactionFlowProperty' already exists.

I have also experimented with testing scalability by hitting the service using thor, and have noted that InstanceContextMode.Single behavior is the most responsive and reliable.

I’d like to acknowledge Zhuyun Dai’s article at CodeProject for giving useful insights with regards to using byteStreamMessageEncoding.

Listening to FM radio using RTL-SDR


I am tinkering with an RTL-SDR dongle to listen to FM radio, on a MacBook Pro with OS X Yosemite, and a Windows 8.1 VM running on Parallels Desktop 10. There are several software options available. I’ll go into those that I tried, others that I didn’t, and one that is surprisingly good.

librtlsdr

This is a multi-platform library available as open source. On Mac OS X, you can obtain it using homebrew

brew install librtlsdr

Here’s how you can use the rtl_fm sample available with the library, to record wide-band FM

rtl_fm -f 88700000 -M wbfm - | ffmpeg -f s16le -ar 17000 -ac 2 -i - wbfm.wav

I pipe the output of rtl_fm, which is in signed 16-bit little-endian PCM format, to ffmpeg to produce a WAV file. The WAV file can then be played using Audacity, or any music player of your choice.

SDR#

SDR# is a Windows freeware that used to be open source in the past. It is fairly easy to listen to FM radio by following the SDR# FM radio tutorial from Adafruit. The quality of audio is not so good on a Windows VM.

I attempted to build an older open source version of SDR# using Xamarin Studio for Mac OS X. It fails to run because run-time dependencies such as libsndfile and portaudio, installed through homebrew, are 64-bit binaries. 64-bit build of mono 3.12.0 and libgdiplus (the latter depends on cairo installed through homebrew) from source also does not work due to crash in native code invoked by System.Windows.Forms.XplatUICarbon.CGDisplayBounds. Windows Forms on 64-bit Mono on Mac OS X is currently a no-go.

There’s HDSDR, another Windows freeware, that I haven’t tried. A Mac OS X port of gnuradio is something else I want to try, but it is only available through MacPorts. I don’t use MacPorts, and building gnuradio from source looks daunting due to the number of dependencies.

Radio Receiver Chrome App

Radio Receiver

The open source Radio Receiver App from a developer at Google, is probably the best way to listen to FM radio using RTL-SDR. The sound quality is awesome, and it’s mostly implemented in JavaScript! How cool is that!?

Monthly news review


This post reviews news in the month that has passed. Comment below to leave your opinion.

$150 Smartphone spectrometer can tell the number of calories in your food

Not a day goes by without a new accessory for Smartphone being unveiled. We now have accessories for everything from health to payments. A miniature spectrometer is however something unheard of, especially one backed by a cloud service that learns from every scan. One step closer to the tricorder. Awesome.

The perfect iOS email app finally exists

Accompli is being touted as a better (nay perfect) e-mail app. Like Outlook, it has mail, calendar and contacts, all working seamlessly. The attachments view is fantastic to quickly find and send attachments. There are a few rough edges, which is to be expected in a freshly baked app.

HTML5 apps can be just as speedy as native apps with the new Famo.us Javascript framework

The Famo.us open source framework is tackling performance of mobile browsers as a platform problem aka HTML5 head-on. Currently, their site is invite-only, which I received a couple of days back. I’ve been through their demos using Chrome for Desktop and iOS and they are stellar.

Car-hacking: A New Fear For Drivers of Tech-Loaded Vehicles

As our cars get more tech savvy and connected, they’ll be more prone to the same kinds of vulnerabilities that affect other computing devices. While you are still driving around in your old(ish) car you can still do some neat things this month: use CarPlay if you have the right system from Pioneer, control your Smartphone hands-free using Bluetooth LE, evaluate your driving performance, and get haptic feedback to avoid running into trouble. The latter is rather ambitious.

Massive Security Bug In OpenSSL Could Affect A Huge Chunk Of The Internet

I hope you have heard of this flaw already. Otherwise, stop whatever you’re doing, update your computer systems, review what your service providers have done about it, and change your passwords on compromised services. It is serious and needs immediate action. The sad thing is that the flaw has been known to some for a while.

Now, when did our governments decide they could spy on us without using the legal system? Brazil has taken the first steps to prevent that kind of thing from happening by passing an Internet Bill of Rights (text in Portuguese).

Amazon unveils Fire TV

Amazon has taken a leap over Apple’s hobby by creating a device for its Prime subscribers. It also looks like a nice low-end game console, no console (pun intended) there for Nintendo and others. If I were Nintendo, I would stop making consoles (sold at cost) and make money on mobile games. Amazon has also subtly changed their branding by not calling it Kindle Fire TV.

Microsoft Launches .NET Foundation

Microsoft is recognizing the fact that the .NET community is keen on using C# everywhere. A C# programmer can now target several platforms thanks to Xamarin. Reuse is the keyword that comes to mind when thinking of .NET these days. It used to be so with Java, and thanks to Google and Android it still is (somewhat). Oracle, though, wants to litigate instead of fanning the embers.

In related news, Microsoft has also announced that Windows for the internet of things will be free. That includes all devices with screen size under 9 inches. And, PC users can now update Windows 8.1. Slowly and steadily Microsoft has made Windows 8 more PC-user friendly.

Getting started with Apache Cordova


Apache Cordova, or PhoneGap, is a cross-platform HTML5 app development framework. It allows creation of offline HTML5 and hybrid applications. This post recounts my brief experience getting started with Apache Cordova. It is relevant for Android and iOS, and assumes you are developing on a Mac.

Install Node

Grab the Node installer for Mac and install it. You’ll need it for installing Cordova. The cordova command line utility is based on Node.

Install Cordova

After Node has been installed, use npm to install Cordova

sudo npm -g install cordova

Use cordova --version to check the version of Cordova. In my case it’s currently

3.0.6

Create HTML5 app

A new Cordova HTML5 app can be created as follows

cordova create myapp com.mycompany.MyApp MyApp

A new folder called myapp is created, and the HTML5 resources are created under myapp/www.

Create platform-specific apps

An iOS app to build and deploy the HTML5 app can be created thus

cordova platform add ios

You’ll require Xcode, download it from the Mac App Store if you don’t have it installed. The command above does not work with the preview release of Xcode 5.0, I had no problem with Xcode 4.6. Cordova will create platform-specific files for iOS under myapp/platforms/ios, including a Xcode project to build and deploy the native application. The project opens and builds with the preview version of Xcode 5.

Cordova also copies the HTML5 app from myapp/www to platforms/ios/www. Remember to add the latter folder to .gitignore if you use Git for version control.

To create an application to deploy on Android

cordova platform add android

You’ll need to have Android SDK in PATH. Since I use Android Studio, here’s how I modified my PATH variable

export PATH=$PATH:/Applications/Android\ Studio.app/sdk/tools:/Applications/Android\ Studio.app/sdk/platform-tools

The Android project structure under myapp/platforms/android does not work with Android Studio, but builds with ant. Eclipse ADT can be used to migrate the project to Gradle and Android Studio. A Gradle based build setup is under consideration but may not happen soon.

Build and test platform-specific apps

The iOS app can be built and deployed using the Xcode project under myapp/platforms/ios.

To build the android app run ant under myapp/platforms/android

ant debug

Deploy using adb

adb install -r bin/MyApp-debug.apk

Iterate and build

Every time you change the app in myapp/www, you’ll need to run

cordova prepare ios
cordova prepare android

Then, perform the platform-specific build steps described earlier.

The performance on iPhone 4S with iOS 7 is quite acceptable. It not as smooth on a Samsung Galaxy S3 (Android 4.2.2). Lesser Android Smartphones may struggle.

Serving static web content using WCF


This post demonstrates how static web content can be served from a WCF service using WebHttpBinding and webHttp behavior.

Service Interface

The service has just one method in its interface called StaticContent.

using System.IO;
using System.ServiceModel;

namespace WwwService
{
    [ServiceContract]
    interface IWwwService
    {
        [OperationContract]
        Stream StaticContent(string content);
    }
}

Service Implementation

The implementation of the service is shown below. The StaticContent method returns a FileStream with the content of the requested resource, and sets the content type and HTTP status code.

using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;

namespace WwwService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class WwwServiceImplementation : IWwwService
    {
        [WebInvoke(Method = "GET",
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "/{*content}")]
        public Stream StaticContent(string content)
        {
            OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
            string path = "www/" + (string.IsNullOrEmpty(content) ? "index.html" : content);
            string extension = Path.GetExtension(path);
            string contentType = string.Empty;

            switch (extension)
            {
                case ".htm":
                case ".html":
                    contentType = "text/html";
                    break;
                case ".jpg":
                    contentType = "image/jpeg";
                    break;
                case ".png":
                    contentType = "image/png";
                    break;
                case ".ico":
                    contentType = "image/x-icon";
                    break;
                case ".js":
                    contentType = "application/javascript";
                    break;
                case ".json":
                    contentType = "application/json";
                    break;
            }

            if (File.Exists(path) && !string.IsNullOrEmpty(contentType))
            {
                response.ContentType = contentType;
                response.StatusCode = System.Net.HttpStatusCode.OK;
                return File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            }
            else
            {
                response.StatusCode = System.Net.HttpStatusCode.NotFound;
                return null;
            }
        }
    }
}

You may want to add additional content types to the switch statement above, or implement an externally configurable mapping scheme.

Hosting the service

Here’s the App.config for the service.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBinding"/>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttp">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="WwwService.WwwServiceImplementation">
        <endpoint address="http://localhost:8003/wwwservice" binding="webHttpBinding" bindingConfiguration="webHttpBinding" contract="WwwService.IWwwService" behaviorConfiguration="webHttp"/>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

Here’s a console program that hosts the service configured above.

using System;
using System.ServiceModel;

namespace WwwService
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(WwwService.WwwServiceImplementation));
            host.Open();

            Console.WriteLine("Hit Enter to quit.");
            Console.ReadLine();
        }
    }
}

Where to put static content

Create a folder called www inside the folder where the service is started, store your static content there, and name the default web page index.html. Then, when the browser requests content starting with the URL http://localhost:8003/wwwservice, it will be served static content by the StaticContent method, or returned a Not Found status code.

Cleaner JSON from a WCF service with webHttp behavior


This post improves on an earlier post, Consuming WCF services using JQuery JSON. The JSON serialized by the WCF service in that post is wrapped inside a d property. In this post we modify the service to return cleaner JSON by using webHttp behavior, and WebInvokeAttribute class.

Self-hosted WCF service

The code example follows. Note that we have removed the WebGetAttribute class from the methods in the service contract interface, and added WebInvoke attribute to the methods in the service implementation.

using System;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace wcf
{
    [ServiceContract]
    interface IMyService
    {
        [OperationContract]
        void SetSomething(string something);

        [OperationContract]
        string GetSomething();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    class MyService : IMyService
    {
        string _something = String.Empty;

        #region IMyService Members

        [WebInvoke(Method = "GET",
                   ResponseFormat = WebMessageFormat.Json,
                   UriTemplate = "SetSomething?something={something}")]
        public void SetSomething(string something)
        {
            _something = something;
        }

        [WebInvoke(Method = "GET",
                   ResponseFormat = WebMessageFormat.Json,
                   UriTemplate = "GetSomething")]
        public string GetSomething()
        {
            return _something;
        }

        #endregion
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(wcf.MyService)))
            {
                host.Open(); // end point specified in app config

                Console.WriteLine("Hit Enter to quit.");
                Console.ReadLine();
            }
        }
    }
}

app.config

The modified app.config follows. Note that the behavior is now webHttp instead of enableWebScript.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttp">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="wcf.MyService">
        <endpoint address="http://localhost:8003/myservice"
          binding="webHttpBinding"
          contract="wcf.IMyService"
          behaviorConfiguration="webHttp"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

jQuery test app

The code follows. Only difference being, we don’t access the d property to read value returned by the service. We can send parameters in the URI instead of query string, now that we use UriTemplate.

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
    <script type="text/javascript"
      src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.1.min.js">
    </script>
    <script type="text/javascript">
        var url = 'http://localhost:8003/myservice/';
        $(document).ready(function () {
            $("#set").click(function () {
                var urlSet = url + 'SetSomething?something='
                    + $("#text").val();
                $.getJSON(urlSet, function (data) {
                    // nothing to do
                });
            });

            $("#get").click(function () {
                var urlGet = url + 'GetSomething';
                $.getJSON(urlGet, function (data) {
                    $('#text').val(data);
                });
            });
        });
    </script>
  </head>
  <body>
    <p>Test MyService</p>
    <form action="">
      <input id="text" type="text" value="Hello" />
      <input id="set" type="button" value="Set"/>
      <input id="get" type="button" value="Get" />
    </form>
  </body>
</html>

Support cross-origin requests

Cross-origin (CORS) requests are easily supported by adding a custom behavior as documented here.