Click here to Skip to main content
15,880,972 members
Articles / Web Development / Node.js

Node.Js: As A WebSocket Relay and Possible Filter

Rate me:
Please Sign up or sign in to vote.
4.82/5 (3 votes)
4 Mar 2014CPOL2 min read 24K   7   4
Node.js: as a websocket relay and possible filter

I was at work the other day and my boss was pushing (nicely) my team lead and me to create a XMAS present for him. What we basically wanted was to capture certain information about certain events that were occurring in the system in real time and have them sent to a web site. I have done something like this in the past using Duplex WCF and MSMQ and SignalR.

This time, I thought I just can’t be bothered to write all that plumbing and thought about it, and I decided we could go with a simple node.js server, that would serve up a static HTML page. The static HTML page would use the node.js and one of the awesome node.js packages, namely socket.io. I am fully aware of the awesome Fleck WebSocket library, that does indeed allow you to send data from a .NET client directly to a static HTML page using the Fleck WebSocket API.

The thing is we wanted to filter out certain things, which was not really achievable using Fleck, and it is something that socket.io does very well, so we went with socket.io. I am now going to show you the code, it should however be noted that the code below doesn’t include any filtering, but that is possible using socket.io, where you can broadcast, only send to certain client, send a private message and so on, it really is very good.

So what does the code do again, well it allows a .NET Client to send data via a WebSocket to a node.js server, where it is read and pumped out to a static HTML page using socket.io. Here is the entire code for the .NET client.

C#
public class DemoMessage
{
    public int Type { get; set; }
    public string Description { get; set; }

    public DemoMessage(int type, string description)
    {
        this.Type = type;
        this.Description = description;
    }

    public DemoMessage()
    {

    }
}

class Program
{
    internal static DataContractJsonSerializer jss;

    public async void Run()
    {
        int messageId = 1;
        bool shouldRun = true;
        string exitCode = "Q";

        try
        {
            while (shouldRun)
            {
                Console.WriteLine("Enter you new message value");
                string dataEntered = Console.ReadLine();

                if (dataEntered.Equals(exitCode, StringComparison.CurrentCultureIgnoreCase))
                {
                    shouldRun = false;
                }
                else
                {
                    WebClient client = new WebClient();
                    NameValueCollection values = new NameValueCollection();
                    DemoMessage mess = new DemoMessage(messageId++, dataEntered);
                    AddValue(values, "DemoMessage", mess);
                    Console.WriteLine("Uploading values");
                    client.UploadValuesAsync(new Uri("http://localhost:3000/MessageReceive"), values);
                }
            }

        }
        catch (Exception ex)
        {
        }
    }

    static void Main(string[] args)
    {
        new Program().Run();
    }

    internal static T GetValue(Byte[] results) where T : class
    {
        using (MemoryStream ms = new MemoryStream(results))
        {
            jss = new DataContractJsonSerializer(typeof(T));
            return (T)jss.ReadObject(ms);
        }
    }

    internal static void AddValue(NameValueCollection values, string key, object value)
    {
        jss = new DataContractJsonSerializer(value.GetType());
        using (MemoryStream ms = new MemoryStream())
        {
            jss.WriteObject(ms, value);
            string json = Encoding.UTF8.GetString(ms.ToArray());
            values.Add(key, json);
        }
    }
}

And now onto the node setup. I am using node with Express, and full instructions can be found in the node codes README.txt (though if you download the attached code, you won’t need to do anything other than install node.js) the node.js application:

JavaScript
var express = require('express');
var mess = require('./routes/messageReceive');

var http = require('http');
var path = require('path');
var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
//app.set('views', __dirname + '/views');
//app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

var server = http.createServer(app);
var io = require('socket.io').listen(server);

app.post('/MessageReceive', function (req, res) {
    mess.ReceivePost(req, res, io);
});

server.listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});
1
It can be seen from this that there the "Static" content 
can be served from the "public folder", 
and there is a single route which accepts the POST data, called "MessageReceive"
1
exports.ReceivePost = function (req, res, io) {

    console.log('RAW body' + req.body);

     var requestJsonString = JSON.stringify(req.body);
     console.log('STRINGIFIED body' + requestJsonString);

     var requestJson = JSON.parse(requestJsonString);
     console.log('requestJson :' + requestJson);

     var messageJson = JSON.parse(requestJson['DemoMessage']);
     console.log('messageJson " ' + messageJson);

     console.log('Message Seen');
     console.log('Type was :' + messageJson.Type);
     console.log('Description was :' + messageJson.Description);

     io.sockets.emit('newMessage',
         {
             type: messageJson.Type,
             description: messageJson.Description
         });
     res.write('ok');
};

So this code takes the request (from .NET code) and sends it out on the WebSocket. The last piece of the puzzle is the static HTML page that will be the client end of the WebSocket. Let's look at that next. Which is shown below:

JavaScript
$(document).ready(function () {

    var socket = io.connect('http://localhost');
    socket.on('newMessage', onNewMessage);
    alert('In the Demo page');
});

function onNewMessage(data) {
    console.log('onNewMessage');
    console.log(data);
    alert('message description ' + data.description + ' message type ' + data.type);
}

All you need to do it is run the node command line, change to the directory where you have the node code, type "code app.js" and then launch a browser and point it to http://localhost:3000/demopage.html and then run the .NET code, and send some messages, you should see the static HTML alert your typed .NET messages. Enjoy!

As usual, here is a small demo app: NodeRelay.zip.

This article was originally posted at http://sachabarbs.wordpress.com/2013/10/24/1329

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
QuestionYou're a mentalist Pin
Anas Karm.5-Mar-14 21:49
Anas Karm.5-Mar-14 21:49 
AnswerRe: You're a mentalist Pin
Sacha Barber6-Mar-14 0:27
Sacha Barber6-Mar-14 0:27 
QuestionRe: You're a mentalist Pin
Anas Karm.6-Mar-14 0:59
Anas Karm.6-Mar-14 0:59 
AnswerRe: You're a mentalist Pin
Sacha Barber6-Mar-14 2:49
Sacha Barber6-Mar-14 2:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.