Wednesday, March 26, 2014

Play Framework Comet / Chunking Support



So my first choice when it comes to full duplex communication with a web server is websockets. Play has amazing support (non-blocking/async) support for websockets and there are plenty of example inside activator templates. But what do we do for those browsers that don't support websockets? In particular Android default browser 4.3 (Jellybeen) and below.

Note: 4.4+ Kitkat will now have chrome as the native browser [websockets, webrtc, webgl, and much more]

In cases like this we need to fallback to some form of "comet" or "long-polling" technique. However in the spirit of play we want to be non-blocking and asynchronous with our approach. With a little bit of digging on google we can find some info on how this was done in play 2.0. This stackoverflow article talks a bit about how comet works in play 2.0

public static void newMessages() {
    List messages = Message.find("date > ?", request.date).fetch();
    if (messages.isEmpty()) {
        suspend("1s");
    }
    renderJSON(messages);
}

The key bit here is suspend("1s") which is what holds the HTTP request open, checking for new data once per second.

However suspend is not going to work for us in play 2.1+ so we need to find another solution. A number of things changed from 2.0 to 2.1 and in particular the "SimpleResult" is now the return type for all actions. They have done away with the other result types and folded them in under simple result. There are some good notes here on migrating to play 2.2. One of the things we can see is the use of a Chunked result

Working with chunked results

Previously the stream method on Status was used to produce chunked results. This has been deprecated, replaced with a chunked method, that makes it clear that the result is going to be chunked. For example:

def cometAction = Action {
  Ok.chunked(Enumerator("a", "b", "c") &> Comet(callback = "parent.cometMessage"))
}

Advanced uses that created or used ChunkedResult directly should be replaced with code that manually sets/checks the TransferEncoding: chunked header, and uses the new Results.chunk and Results.dechunk enumeratees.

So this looks promising. However we still need to make a choice on what we are going to do as a generator for the Enumerator. My first idea was to use to use Enumerator.fromCallback1. This looked like it should work, and even compiles fine, but no chuncked response. After doing some digging I found that my return type looked a little strange and that this may be a bug in "fromCallback1". I found someone else having the same issue in this post here.

Next I played around with a Promise.timeout and a Enumerator.generateM. There is an example of this style of comet usage on the comet-clock. The lines to note here are the following:

Enumerator.generateM {
   Promise.timeout(Some(dateFormat.format(new Date)), 100 milliseconds)
}

...

def liveClock = Action {
   Ok.chunked(clock &> Comet(callback = "parent.clockChanged"))
}

After some more time trying to get this new approach to work, I stumbled into a discussion around Concurrent.broadcast. Which as it turns out... is exactly how I am doing my producer / consumer for my websocket... doh! Should have looked here right at the start :)

Concurrent.broadcast

This article on stackoverflow talks about the Concurrent.broadcast. After a little bit of time playing with this I got a working example. Here are the steps involved.

First you need to get you producer and consumer tuple.

   val (cometOut, cometChanel) = Concurrent.broadcast[JsValue]

Now you can use the cometChannel to push Json data into the cometOut Enumerator.

   cometChanel.push(Json.obj("data" -> "test"))

And finally you can plug your enumerator into the play Comet helper for a chuncked data response.

   Ok.chunked(cometOut &> Comet(callback = "parent.cometMessage"))

Chuncked response and what can go wrong

First off the comet helper in play does some "padding" to get around an issue with chunking. This can be seen with this gist.

 def apply[E](callback: String, initialChunk: Html = Html(Array.fill[Char](5 * 1024)(' ').mkString + ""))(implicit encoder: CometMessage[E]) = new Enumeratee[E, Html] {

Note the Array.fill[Char](5 * 1024)(' ').mkString. So if you are not using the Comet helper in play, you will need to do something similar to have your chunked response work. You can find more information on this here.

Nginx and HTTP 1.1

If you are using nginx to proxy your request like I am, then there are further problems to deal with. First Nginx defaults to HTTP 1.0 which does not have chucking support. You need to explicitly tell your nginx config to use HTTP 1.1.

   location / {
     proxy_http_version 1.1;
     proxy_pass http://localhost:9009/;
     proxy_set_header Host $http_host;
  }

There is another problem

If you view your endpoint now using curl, everything will work fine... but wait. If you try your comet solution in chrome or firefox you will get the infinite loading spinner and you will never see any chunked data until the http request is closed.

If you point your browser directly at play however you will notice that everything is working fine. This again points to a problem within nginx. After using curl to examine the headers for both request, I noticed that nginx response headers contain the line Connection: keep-alive. Browsers seem to wait for the connection to close for a chunked transfer before returning the data.

So we are left trying to get rid of the Connection: keep-alive from the nginx response headers. Unfortunately this is not a configurable option inside nginx and you are left patching it from source. I have posted a comment here.

Update: The solution is to turn GZIP off for nginx
The white space that play pushes into the buffer (described about) obviously compresses very well with gzip... totally defeating the purpose of the buffer to begin with. The solution is to turn off gzip. NOTE: that I don't like this solution and will be looking for alternatives to play http 1.1 chunking.

Update: There is more info surrounding this issue in the above post

Nginx Websocket configuration

https://github.com/dryan/decss-sync/issues/1

Also ran into problems with nginx closing the socket after 1 min. This is related to proxy_read_timeout.. more about this here http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout.

Thursday, December 26, 2013

Neo4J user service plugin for secure social (play framework/scala)

SecureSocial-Neo4JUserService

Neo4J user service plugin for secure social (play framework/scala)

Project on GitHub: SecureSocial-Neo4JUserService


Background

Building reactive web applications with play framework and scala often starts with a social login system. One great way to get started here is to use Secure Social. They provide a simple way to get up and running with a large number of providers. Once you are running you will need to store your account information and more the likely the relationships between your social users "friends". This is where Neo4J really shines.

Requirements

Setup

Once you have secure social up and running all you need to do is add this scala file to your play project. I created a app/servicies directory to place the file. Next you simply need to add a line to your play.plugins

play.plugins

9998:service.Neo4JUserService

Neo4J Structure

Users will now be added to your neo4J with the following structure

(u:User)-[:HAS_ACCOUNT]->(p:Provider)

You can also use the utility methods outlined below to make users friends

(u1:User)-[:FRIEND]->(u2:User)

Helper methods

Here are number of usefull methods for helping you to work with secure social and Neo4J

object  Neo4JUserService{
  def socialUserFromMap( umap: Map[String, String]): Identity = {
    ...
  }

  def makeUsersFriends( uuid1: String, uuid2: String ) = future{
    ...
  }

  def socialUserFromToken(provider: String, token: String) = future{
    ...
  }

  def uuidFromProviderInfo( provider: String, id: String, name: String = "" ) = future {
    ...
  }


  private def createUserAndProvider(name: String, id: String, fullname: String) = {
    ...
  }
}

Things to consider.

You will still need a way for users to "link" multiple providers on your back-end. Currently if a user signs in using another provider, they will get another user and provider record in Neo4J. You could try to combat this at the login level by looking for emails that are same as other providers (you would want to verify the email before linking for security reasons)

Another way would be a settings section on your site when a user is loged in, that would allow them to "link" their other accounts. In this manor you would want to create to continue to build a structure like the following

        /[:HAS_ACCOUNT]->(p0:Provider)
(u:User)-[:HAS_ACCOUNT]->(p1:Provider)
        \[:HAS_ACCOUNT]->(p2:Provider)

Tuesday, December 10, 2013

Base3d a simple c++ library

Base3d lib C++

GitHub https://github.com/coreyauger/cpp_base3d_lib

Overview

This is a small and simple base 3d library written in C++. You would be crazy to write your own 3d library in todays world… However there are still a number of applications for using a compact 3d library to learn from or implement application specific problems.

This code was written a while back but used in a number of 3d applications during my time in University. I have decided to share it in the hopes that someone could find it as useful as I once did.

Example projects

Collision Detection Project

This project I designed a large "ball" course that I let serve as a demonstration of the physics I wrote. This was a super fun project and ended up working very well.

demo 1

Water Simulation

This was a really fun project to work on. The main idea for the movement of the water came from one of my favorite sites on the net: The good-looking textured light-sourced bouncy fun smart and stretchy page

demo 1

Radiosity

Dividing each face of our scene into light-map texel regions, we are going to perform a gathering type of radiosity solution. First by using GL to render the scene from the perspective of a texel into a hemi-cubed texture map, we solve the visibility problem. More info here

demo 1

Monday, December 9, 2013

FLV Socket Writer Direct Show Filter

flv socket filter

Project on GitHub: https://github.com/coreyauger/flv_socket_filter

Windows Direct Show filter. Stream FLV and header information to any connecting application. Takes care of late joiners by resending h264/aac headers.

Overview

FLV files consist of a single header, and metadata, chunk followed by N interleaved audio and video chunks.
Most streaming filter implement RTMP and provide a single client with the ability to connect and start injesting a stream.
This filter provides a much more flexible and free form way of Interprocess Communication with you data.

  • Supports M number of simultaneous connection steams to FLV
  • Supports "late joiners" headers(Meta,Head) + AAC/H264 packets are retransmitted to new connections
  • Actionscript ByteStream clients will receive data on chunk boundaries for easy parsing.
  • Simple to right stream out to file on disk at the same time as other operations.

Requirements

The only requirement are the direct show base classes. Sockets are winsock implementation.

Usage

Currently the filter has the listening port hardcoded. You could add this as an option to the filter option page if you so desire. Once this filter is up and running you can connect to it via the port number and start to injesting your FLV.

Example

Here is an example client written in C# that will connect and write the FLV to disk.

This example uses the FlvStream2FileWriter that is also an open source project I have on GIT here: (https://github.com/coreyauger/flv-streamer-2-file)[https://github.com/coreyauger/flv-streamer-2-file]

This takes care of inseting the new timing information into the FLV so that your file on disk will allow seek operations.

internal void SaveStreamToFile(string path)
        {
            const int count = 4096;
            byte[] buffer = new byte[count];

            // Declare the callback.  Need to do that so that
            // the closure captures it.

            AsyncCallback callback = null;

            System.IO.File.Delete(path);
            FlvStream2FileWriter stream2File = new FlvStream2FileWriter(path);

            // Assign the callback.
            callback = ar =>
            {
                try
                {
                    // Call EndRead.
                    int bytesRead = _clientStream.GetStream().EndRead(ar);

                    // Process the bytes here.
                    if (bytesRead != buffer.Length)
                    {
                        stream2File.Write(buffer.Take(bytesRead).ToArray());
                    }
                    else
                    {
                        stream2File.Write(buffer);
                    }

                    // Determine if you want to read again.  If not, return.                
                    // Read again.  This callback will be called again.
                    if (!_clientStream.Connected)
                    {
                        throw new Exception("Just catch and exec finallize");
                    }
                    _clientStream.GetStream().BeginRead(buffer, 0, count, callback, null);
                }
                catch
                {   // most likly discontinuity ...just fall through                   
                    stream2File.FinallizeFile();
                    return;
                }               
            };
            _clientStream = new TcpClient("127.0.0.1", 22822);  // (CA) TODO: make port configurable on the filter and here
            // Trigger the initial read.
            _clientStream.GetStream().BeginRead(buffer, 0, count, callback, null);
        }

Wednesday, December 4, 2013

Blue Tooth Low Energy Scanner for Android written in scala

android-scala-ble

Blue Tooth Low Energy Scanner for Android written in scala

Overview

This project serves to wrap up some common functionality regarding scanning for a BLE sensor device.
Right now the code is simple and to the point. Install a filter (device name, mac address) and then start scanning for devices.

Features

I will try to keep adding to this list as I go. For now here is a short list of features:

  • Scan for a BLE sensor devices
    • Filter device list
  • Callback function to report device and signal strength

Example Usage

class MainActivity extends Activity with BleDeviceScanner{
  // Notice the "with BleDeviceScenner"
  // ...

  @Override
    protected override def onCreate(savedInstanceState: Bundle) = {
      // ... normal android init
      initBleScanner(this)

      val bscan = findViewById( R.id.bscan ).asInstanceOf[Button]
        bscan.setOnClickListener(new View.OnClickListener {
          override def onClick(v: View) = {         
             val filter = {
                d: BluetoothDevice =>
                    d.getName() != null     // You could filter by device name or address here..                                    
              }
              startScanWithFilter(filter){
                di: BleDeviceInfo =>  // This ia a callback with the located device 
                  Log.d(TAG,"Found device[%s] with signal stregth: %s".format(di.getBluetoothDevice.getAddress, di.getRssi) )
              }             
          }
        })

    }

}

Example Projects

Was used in a hackathon to try to do accurate indoor positioning. We ended up having to make a ton of modifications since the TI Sensor Tag can not be used to accuratly interpolate position.

Here is a screen shot TODO://

Monday, December 2, 2013

Create better native UI with Awesomium

awesomium.ui



Source on Github

Create amazing UI the way it should be done... with awesomium.ui.
This is a starter kit for the Awesomium browser based UI and WInform.

Dependencies

Awesomium http://awesomium.com.

Overview

Creating Web UI is easy and fun. With the enormous amount of power built into a modern HTML5 browser, creating fluid rich UI is a breeze.

This is not true when creating Native Application UI. The process is plagued with subtleties that slowly crush developers spirits and ultimately produce projects that take more time and do far less.

Fortunately for us there are ways to bridge the gap between web and native. One of those project is http://awesomium.com/. Awesomium gives you C# wrappers to an underlying Chromium based browser. What does these mean for developers….

All the great features like:

  • CSS3
  • Canvas
  • SVG
  • WebGL
  • WebRTC
  • WebSockets
  • And much more …

You can even run web plugins… think Flash or Unity. Side Note: Awesomium has a Unity3d plugin for Mac/Windows game builds.. also very cool.

Inspiration

Game companies have been doing this for years. Both “Stream” and “Origin” are native browser based UI. The goal with my project is to provide some simple extensions to the Awesomium based libraries that get you up and running fast. Also to provide a good looking UI example … Similar to “Steam” and “Origin”

UI 1

Usage

I have provided a demo project that you can refrence to get you up and running. The basic idea is this:

  • Create a Native Winform project for you solution.
  • Reference

    • Awesomium.Core.dll
    • Awesomium.Windows.Forms.dll
    • awesomium.ui
  • Create a Winform. In my example project I used the default “Forms1.cs”

  • Open the Form1.cs and replace the inherited base class from “Form” to my base class “awesomium.ui.FromBase”
  • Now create a directory in your project called “.appui”

  • Create an html page inside “.appui” directory that has the same name as your Winform. Inside my demo this file was “Form1.html” Make sure to change the “Build Action” for all your html/css/img content to “Content” and “Copy if newer”. This will move the html to your output folder when you build your project.

  • Compile and run the project and you will now have amazing looking UI that has limitless possibilities.

Communication

Communicating with your UI layer is a breeze. This is all done through javascript and json. There are 2 directions for your communication

HTML UI to Native C-Sharp

Inside you javascript create a call like so

ScriptInterface.call('JSMyMethod', 'arg1','arg2');

The first argument is the name of the method in your C# to call. All additional argument are arguments to that function.

On your C# side you would define a method like so:

public void JSMyMethod(string a, string b){
    // do stuff..
}.

C# to HTML javascript

simply use the interface

base.Webbrowser.ExecuteJavascript( "javascript to execute in here" );

Demo Project

UI 2

Sunday, December 1, 2013

DirectShow AudioLoopbackFilter

Source code on Github

AudioLoopbackFilter

Directshow Audio Loopback Capture Filter

Dependencies

Microsoft SDK (Direct Show base classes) http://www.microsoft.com/en-ca/download/details.aspx?id=8279

Overview

This project provides an efficient working audio capture source filter. A “what you hear is what you get”. The code is based on Microsofts IAudioCaptureClient running in “loopback” mode. A feature that has been added since Windows Vista.

Past Work

This code is based on the initial work done by “Maurits” at Microsoft. His work and all the comments containing some of the issues with the code are located here.

Additionally “Roger Pack” wrote the original directshow filter wrapper for Maurits code. Roger’s work can be found here: https://github.com/rdp/virtual-audio-capture-grabber-device. I found that in Windows 8 the filter no longer worked on this project. I also submit a patch that fixed the audio in windows 8.. but the filter graph would pause if there was silence (no audio).

The main issue with these works, is the inability to generate “silence”. This problem is magnified in directshow by not allowing your filter graph to process any video unless there is valid audio (ie silence will pause your graph).

My Solution

I based my filter off the Synth Audio Source, from the directshow example projects. I have removed most of the source that was not needed for my filter to make it easier to understand.

There are a few major differences in my filter from the one I was using before.

  • I generate silence values into the buffer when there is “No” data available from the AudioCaptureClient. This will allow the filter graph to continue to process video frames/mux even if there is no audio.

  • I sync the Reference clock to use the clock time specified by the AudioCaptureClient. This eliminates the usage of the extra threading and BAD sleep statements in the code. The result is a significantly lighter CPU footprint.

Finally

My solution has only undergone a very small amount of testing. Which did include both a Windows 7 and Windows 8 machine. However, if you have any trouble with the filter please contact me and I will be glad to help. Thanks.