1

I'm configuring a nodejs server in order to use it as a server for push notifications.

I have this code:

io.sockets.on('connection', function(socket) {
    console.log(socket);
    // watching the xml file
    fs.watchFile('client.xml', function(curr, prev) {
        // on file change we can read the new xml
        fs.readFile('client.xml', function(err, data) {
            if (err)
                throw err;
            // parsing the new xml datas and converting them into json file
            parser.parseString(data);
        });
    });
    // when the parser ends the parsing we are ready to send the new data to the
    // frontend page
    parser.addListener('end', function(result) {
        socket.volatile.emit('notification', result);
    });
});

On server. And on client this one:

<script>
    function test(data) {
        console.log(data);
        jQuery('#' + data.id).html(data.content);
    }
</script>

<script>
    // creating a new websocket
    var socket = io.connect('http://10.0.0.113:8000');
    // on every message recived we print the new datas inside the #container div
    socket.emit('data', {id : 'id'});
    socket.set('nickname', {id : 'test'});
    socket.on('notification', function(data) {
        _efbn(data.callback, window, data.response, data);
    });

    /**
     * Función que ejecuta una función por nombre. Puede usar namespaces
     * (algo.algo.algo.funct)
     * 
     * @see http://stackoverflow.com/questions/359788/javascript-function-name-as-a-string/359910#359910
     */
    function _efbn(functionName, context) {
        var args = Array.prototype.slice.call(arguments);
        args = [ args[2], args[3] ]; // Fix para IE.
        var namespaces = functionName.split(".");
        var func = namespaces.pop();
        for ( var i = 0; i < namespaces.length; i++) {
            context = context[namespaces[i]];
        }
        try {
            if (typeof context[func] == 'function') {
                return context[func].apply(this, args);
            }
        } catch (e) {
            console.log(e);
        }
        return null;
    }
</script>

Everything is working as I wish. However, I want to send something like:

socket.set('site', '12345');
socket.set('object', 'ABCDE');

In order to identify which xml should I be listening, instead of being listening allways to client.xml.

How can I do it? I have this on server.js:

id = require('url').parse(req.url, true).query.id;

But, since server its only executed when the connection is open, but no when the socket is open, if the connection between the client and the server fails, when jquery retries to open the socket, id will be null...

Cito
  • 1,659
  • 3
  • 22
  • 49

1 Answers1

3

I would do this instead on the server,

io.sockets.on('connection', function(socket) {
    console.log(socket);
    socket.on('setup', function(config) {
        // use your connection specific config variables like
        var id = config.id; // and then use id in your logic below.
        // watching the xml file
        fs.watchFile('client.xml', function(curr, prev) {
            // on file change we can read the new xml
            fs.readFile('client.xml', function(err, data) {
                if (err)
                    throw err;
                // parsing the new xml datas and converting them into json file
                parser.parseString(data);
            });
        });
        // when the parser ends the parsing we are ready to send the new data to the
        // frontend page
        parser.addListener('end', function(result) {
            socket.volatile.emit('notification', result);
        });
    });
});

And on the client-side,

// creating a new websocket
var socket = io.connect('http://10.0.0.113:8000');
socket.on("connect", function() {
    // Setup your connection on the server-side by providing it
    // some config variables.
    var config = {
        id: "id",
        nickname: "test"
    };
    socket.emit("setup", config);
    // on every message recived we print the new datas inside the #container div
    socket.on('notification', function(data) {
        _efbn(data.callback, window, data.response, data);
    });
});

This way, whenever a new connection is established, the setup event is first called on the server with the required config variables.

Gautham Badhrinathan
  • 2,377
  • 3
  • 20
  • 30
  • Let me check it out. Two last questions. Why are you "emiting" the setup and also data? And why are sending nickname? I mean, how can I get nickname on the server? – Cito Aug 20 '12 at 23:18
  • Excellent! Thanks a lot! this works as expected. Just one final question. If the server goes down, when the connection is restablished, the socket is not emiting the configuration again. How can I do it? I'm really newbie in working with sockets and node.js. – Cito Aug 20 '12 at 23:34
  • I have found it: `socket.on('reconnect', function () {});` Thanks a lot again! – Cito Aug 20 '12 at 23:38
  • Ah, I didn't see the emit data and set nickname part, will edit it out once I get to my computer. – Gautham Badhrinathan Aug 21 '12 at 11:31