Getting started with the Java SignalR SDK

Microsoft has just released a Java SignalR SDK which allows Java and Android clients to access ASP.NET SignalR back ends. The library is open source, and currently it is up to you to build the .jar packages yourself. For your convenience I’ve uploaded my built .jar files. Given that this library as of yet is still fairly undocumented, and I spent quite some time on getting it up and running, I figured I’d provide a short introduction tutorial here. I found the C# SignalR client documentation to be the most useful while figuring out the API as the classes and methods overall seem to correspond. The tests in the GitHub repository are another useful resource. I’ll mainly be focusing on the specific differences in the Java library, and refer you to the original documentation for more elaborate information.

We will create a simple Hub supporting bidirectional communication. A quick and easy way to get a C# back end up and running for the purpose of this tutorial is to self-host a SignalR server in a simple console or WPF application. The following C# code shows a simple hub with one method which can be called by the Java client, SendMessage.

public class MessageHub : Hub
{
	public static event Action<string, string> MessageReceived = delegate { };

	public void SendMessage( string name, string message )
	{
		MessageReceived( name, message );
	}
}

I added a static event handler which can be consumed by the console or WPF front end to display the received message. SendMessage is called from a different thread, so in case you want to update the UI, don’t forget to use a dispatcher!

MessageHub.MessageReceived  += ( name, message ) => _dispatcher.Invoke(
    () => { MessageBox.Content = String.Format( "{0} said {1}", name, message ); } );

Onwards to the client side code! To set up a Java project which can use the SignalR client API, add the ‘signalr-client-sdk.jar’ and ‘gson-2.2.2.jar’ to the project build path. For Android projects the references need to be added differently. Drag the two jars, and the additional ‘signalr-client-sdk-android.jar’ to the libs folder in Eclipse. By doing so they will automatically be added as Android libraries.

As mentioned before, the SignalR Java client follows the same structure as the C# client API, thus setting up a connection is quite similar. However, for Android applications an additional platform component needs to be loaded as shown below; also don’t forget to add internet permission to your manifest file, or you will receive a SocketException when trying to connect.

Platform.loadPlatformComponent( new AndroidPlatformComponent() );
// Change to the IP address and matching port of your SignalR server.
String host = "http://192.168.0.xxx:8080";
HubConnection connection = new HubConnection( host );
HubProxy hub = connection.createHubProxy( "MessageHub" );

This simply configures the connection. Establishing the actual connection is somewhat different than the C# documentation due to limitations of Java. To mimic language support for async in C#, the SignalRFuture class is introduced. Asynchronous operations return an instance of this class, without actually performing any real work yet. What follows is example code of how to start the connection synchronously by calling get() on the SignalRFuture. Don’t forget to cleanly stop() the connection when shutting down the application.

SignalRFuture<Void> awaitConnection = connection.start();
try {
	awaitConnection.get();
} catch (InterruptedException e) {
	// Handle ...
} catch (ExecutionException e) {
	// Handle ...
}

In case your server is up and running, you should now be ready to start listening to and submitting messages. Again, listening to events in C# is more straightforward since it supports lambdas as the C# client API documentation demonstrates.

stockTickerHubProxy.On<Stock>( "UpdateStockPrice", stock => Console.WriteLine(
    "Stock update for {0} new price {1}", stock.Symbol, stock.Price) );

Doing something similar in Java requires elaborate inline anonymous classes, or the creation of a handler class per event you want to listen to. Suppose the server would send a message “context.Clients.All.UpdateStatus( “Online” );”, handling this the ‘C# way’ would like as follows:

hub.on( "UpdateStatus",
    new SubscriptionHandler<String>() {
        @Override
        public void run( String status ) {
           // Since we are updating the UI,
           // we need to use a handler of the UI thread.
           final String fStatus = status;
           handler.post( new Runnable() {
               @Override
               public void run() {
                   statusField.setText( fStatus );
               }
           } );
        }
    }
, String.class );

Therefore, Microsoft has seemingly added a method not available in the C# API to the Java client. Calling hub.subscribe( listener ) where listener is an object implementing corresponding methods for every available incoming event is a much more straightforward way to listen to messages. Under the covers this uses reflection to hook everything up correctly. These methods need to be public!

hub.subscribe( this );
...
public void UpdateStatus( String status )
{
	final String fStatus = status;
	handler.post(new Runnable(){
		@Override
		public void run() {
			statusField.setText( fStatus );
		}});
}

More complex types work as well, as long as it is supported by JSON. I don’t know the specifics, but this will be dependent on the SignalR server and the gson library used by the SignalR Java client. The following code prepares the client to call a new method on the server which you can add to the MessageHub: “public void SendCustomType( CustomType object ) { … }“.

// A simple C# class which can be sent over SignalR.
public class CustomType
{
	public string Name;
	public int Id;
}
// The same type as defined in Java.
public class CustomType
{
	public String Name;
	public int Id;
}

Finally, calling the earlier SendMessage() and the newly added SendCustomType() can be done as follows. As you can see, remote method invocation again returns a SignalRFuture, and a subsequent get() is needed.

try {
    hub.invoke( "SendMessage", "Client", "Hello world!" ).get();
    hub.invoke( "SendCustomType",
        new CustomType() {{ Name = "Universe"; Id = 42; }} ).get();
} catch (InterruptedException e) {
	// Handle ...
} catch (ExecutionException e) {
	// Handle ...
}

Similarly, you can simply pass custom objects from the server to the client by adding the custom type as a method parameter: “public void SomeMethod( CustomType bleh ) { … }

Java Generic Observer

Design patterns, you gotta love them! What would we do without our beloved Observer Pattern? Since its usage is so common, most frameworks provide an implementation out of the box. Microsoft even added a language construct for it to C#, called ‘events‘. As a Java developer, it would seem you are less lucky. Through the years, my unconditional trust in the design of frameworks has been wavering. Java’s default implementation of the Observer pattern is a nice example of what I consider bad design. Perhaps that’s why it’s not even used in the framework itself. (ActionListener in awt)

If you haven’t watched “Despicable Me” yet, stop reading and watch it first! 😉 It’s a great movie. Consider a person (Gru) needing the ability to watch over his minions.

A standard implementation using the framework’s classes would be:

Gru gru = new Gru();
Minion fred = new Minion();
fred.addObserver(gru);
fred.moo();

public class Minion extends Observable
{
    public void moo()
    {
        setChanged();
        notifyObservers("hehehe");
    }
}

public class Gru implements Observer
{
    public void punch(Minion minion) { ... }

    @Override
    public void update(Observable o, Object arg)
    {
        if (o instanceof Minion)
        {
            String s = (String)arg;
            if (s.equals("hehehe"))
            {
                punch((Minion)o);
            }
        }
    }
}

The thing that bothers me (and others) in this implementation is the need for type checking. After browsing around, I found an implementation by Allain Lalonde who addressed this issue by using a dynamic proxy. I found his solution to be really useful, implemented it, and added a small feature which allows extending from a generic AbstractObservable class. The result looks as follows:

Gru gru = new Gru();
Minion fred = new Minion();
fred.addObserver(gru);
fred.moo();

public interface IMinionListener
{
    public void laughing(Minion minion);
}

public class Minion extends AbstractObservable<IMinionListener>
{
    public void moo()
    {
        getEventDispatcher().laughing(this);
    }
}

public class Gru implements IMinionListener
{
    public void punch(Minion minion) { ... }

    public void laughing(Minion minion)
    {
        punch(minion);
    }
}

How it works.

Events are dispatched through an ObserverPool as described by Allain Lalonde. This is a proxy class which forwards calls (as defined by the interface) to a set of listeners, the observers. You can use this pool directly, or extend from AbstractObservable which already creates and wraps it for you.

Possible problems.

As with the original Observable, you might not be able to extend from AbstractObservable since multiple inheritance isn’t allowed. You could use composition instead, and use the IAbstractObservable interface.

AbstractObservable source code

Better solution? (most likely)

I wrote this code a while ago, before I started this blog. While writing, I followed a link on Wikipedia which I wish I found before. It seems there is a free package available called PerfectJPattern, containing componentized design patterns, including the observer pattern. From the looks of it, they also use a proxy approach. The project looks really well maintained, clean, and thoroughly implemented. Next time I develop in Java, I’ll check it out.