Fun with ASP.NET Web API - push-like messaging from one application to multiple subscriber applications - StrathWeb

Strath

March 29th, 2012

Fun with ASP.NET Web API – push-like messaging from one application to multiple subscriber applications

Because ASP.NET Web API is not just for websites

So last time around we built together a small p2p chat app using WPF and ASP.NET Web API. Today, we are continuing our experiments with ASP.NET Web API and setting up a simple push (or push-like) messaging system between different apps using self hosting.

In fact, we’ll use one app (“server”) to push out messages to a number of other apps (“clients” or “subscribers”). Even though we have the (in)glorious WCF callbacks at our disposal, I thought it might be fun to try it that way. Hopefully, that sounds interesting, or at least intruiging. In the process we’ll also serialize custom types to JSON using JSON.NET and pass them between self-hosting applications.

More after the jump.

So what are we trying to do here?

Let’s have one application that’s a controller (let’s call it “server”), and several others that are receivers (let’s call them “clients”). Of course our naming convention here isn’t exactly accurate since logically they will all be web servers running ASP.NET Web API.

Anyway:
– server will be started and running
– at any time a client can show up and subscribe to the server to receive it’s messages. Client can also leave at any time, the server should recognize that
– server will push out objects containing information to all the subscribed clients which will display that

Of course we are simplyfing things here, showing just a pattern. We could easily swap pushing simple objects with pushing complex objects and swap console app with a complex WPF app.

The Beginnings

So we’re gonna have 3 projects – client, server and a class library for the shared entities. I called it, very creatively, ClassLibrary1. Server and client will require AspNetWebApi.SelfHost and JSON.NET packages from NuGet.

We’re gonna start off really simple, with a Message class that is going to be the object passed between the client and the server. We’ll put in into the class library – a separate DLL so that both our client can use it. We will be serializing it into JSON, because I have been getting quite a few questions about how to serialize and POST objects as JSON using ASP.NET Web API and JSON.NET.

The Message class looks like this:

It has a DateTime property which we’ll use to measure the gap interval between creating the object (and sending it) and receiving it on the other end. We decorated the members with [DataMember] attributes and the class with [DataContract] attribute, so make sure the project references System.Runtime.Serialization.

Serializing objects to JSON

The next step is to setup our JSON Serialization formatter. By default ASP.NET Web API will do it in XML. If you go for JSON serialization, it will force you to use DataContractJsonSerializer which, and those who have worked with WCF a lot would certainly agree, is terrible. So we’ll use JSON.NET, and we’ll rely on a technique shared by Henrik Nielsen here. Have a look there and grab the excellent JsonNetFormatter class.

Once we have the JsonNetFormatter class set up in our project (again, see the code by Henrik) the usage is very simple. Whenever we start our self host server, we’ll be telling ASP.NET Web API to use that formatter. See the code below.

So we added our custom JsonNetFormatter (in this cased based on JSON.NET), as the first entry to the Formtters property of HttpSelfHostConfiguration instance (same as used to configure the routes). The same instance is then passed to the constructor of HttpSelfHostServer.

When this is all done, the usage in requests is dead simple.

Whenever we want to post a T object, we call JsonConvert.SerializeObject(T), and pass the output to the constructor of a StringContent object. Then we just set the headers to be “application/json” and we can POST the object using and instance HttpClient. When we pick up this POST request, no type casting is necessary:

And the Message object has travelled through HTTP as JSON.

Stiching it all together

So we covered the basics:
– we have a Message class which will be posted between subscriber and receiver
– we set up JSON serialization using JSON.NET
– we know how to POST using that

Let’s now build our simple apps, and we’ll use the wonderful console for that. Remember to change the target framework of the console apps to .NET 4.5.

Server a.k.a. Sender

What is it gonna do:
– on startup will start the self-host server and start “awaiting” subscribers
– will take keyboard input and upon ENTER press, will send this as MEssage object to all the subscribers
– we’ll keep track of subscribers – any time a new subscriber connects, we’ll be added to the receivers repository, if one of the goes offline it will be removed

To start off we need a subscriber class to represent our subscribers.

Simple enough. Then we’ll just create a simple static class to act as our in-memory repository of subscribers.

We also need a Web API controller that will “listen” or accept subscribers.

As you can see, as we discussed there is no type casting involved, as the object will auto magically deserialize itself from JSON to Message type.

Now all we need to add for the server is whatever is going to happen in runtime.

This is essentially the same bit of code as we had a look at earlier. So when we start the app, we also start the HttpSelfHostServer at port 9000. then we have a silly infinite loop (sorry couldn’t resist putting this in) which means we’ll be waiting for text input forever and take as many new messages as possible and send them to subscribers using PushMessages method.

The last piece of our server is that method.

This is an async method to POST to all subscribers. Again, this is essentially the same code as I showed earlier. We iterate through subscribers – we are using a for loop and counting down, this way we can remove a subscriber which is offline – and instantiate an HttpClient poitning at each one’s IP address. then we post to the “api/main” controller, and show the response. That’s it, simple an effective “push” messaging.

Client a.k.a. Subscriber

Now let’s look at the client, cause it is going to be very similar to the serv with some slight modifications.

But what shall it do functionally?
– upon startup will ask you at which port should it listen
– when the port is given, a self-host server is started
– upn hitting ENTER client connects to the server at its port 9000 and becomes ready to receive messages

The API controller on the client side is merely going to display the messages as they arrive.

Notice we also don’t type cast here (relying on JSON deserialization) and we display the time needed for the Message object to arrive and be shown.

We’ll need a static AppStorage as well:

This way we can access the name from anywhere. This is the Main method of the applciation, very similar to the “server” setup.

We start the HttpSelfHostServer based on the port provided from the keyboard and the IP address read from the DNS host. This IP will be then passed to the server – as upon pressing enter we susbcribe to the server using Subscribe method.

Again, the principle is simple, and the code should be more then familiar by now – we submit a POST to the server at port 9000, apss the Message as a serialized JSON and write out the response. If you recall, once a client is subscribed, it will be getting messages from server.

Trying it out.

Now let’s try this out. Rememeber to run the apps – either from Visual Studio or from the EXE build, as administrator. Also, if you do stuff over the network, remember to open the appropriate ports in the firewall (or just switch off Windows firewall temporarily if you are using it).

Here’s the scenario:
1. run the server window
2. run 3 clients, give each a different port (if you are experimenting on local) or whatever port (if you are experimenting over the network) and hit enter to subscribe to the server

3. you should see the subscribed client notification appearing in the server window

4. start typing in the server window, and hit enter to see the message appearing in the different clients. You should be getting this:

Summary & Source files

Of course this is far from anything useful at this moment. But we have shown how we can make one application “push” messages to a number of other applications via HTTP using ASP.NET Web API. Now imagine how much you can do with that – you could have a set of remotely controlled apps, all being governed from a single place in real time or anything really that you can imagine ;)

Also please note, that each subscriber could do different things with the arriving message. So we could have forms apps, WPF apps, console apps etc. all running along each other and receiving the same message object, and utilizing it in a different way. Neat! Anyway, till next time!

– 3 source projects – client, server & class library (20MB, zip)

Be Sociable, Share!