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...

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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?
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.
I have found it: socket.on('reconnect', function () {}); Thanks a lot again!
Ah, I didn't see the emit data and set nickname part, will edit it out once I get to my computer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.