Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Node.Js : As A WebSocket Relay And Possible Filter

, 4 Mar 2014
Rate this:
Please Sign up or sign in to vote.
I was At work the other day and my boss was pushing (nicely) my team lead and I to create a XMAS present for him. What we basically wanted was to capture certain information about certain event that were occurring in the system in real time and have them sent to a web site. I […]

I was At work the other day and my boss was pushing (nicely) my team lead and I to create a XMAS present for him. What we basically wanted was to capture certain information about certain event 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 bother 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.

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

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 attached code you won’t need to do anything other than install node.js) The node.js application

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 csn 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 peice of the puzzle is the static HTML page that will be the client end of the WebSocket. Lets look at that next. Which is shown below

$(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 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


License

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

Share

About the Author

Sacha Barber
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 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 PinmemberMember 101990435-Mar-14 21:49 
AnswerRe: You're a mentalist PinmvpSacha Barber6-Mar-14 0:27 
QuestionRe: You're a mentalist [modified] PinmemberMember 101990436-Mar-14 0:59 
AnswerRe: You're a mentalist PinmvpSacha Barber6-Mar-14 2:49 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140922.1 | Last Updated 4 Mar 2014
Article Copyright 2014 by Sacha Barber
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid