Frage

I'm not sure that what I'm trying to achieve is the right way to do it because I cannot find any example.

I have an application which is displaying a Google map and multiple objects on it. I want the location of the objects to be updated automatically every seconds or 2.

I was thinking of having a nodejs server with a setInterval() that would be triggered every 2 seconds to perform an API request to a different server, get the data response and broadcast it to all socket.io clients.

Here is my server.js that I'm using at the moment:

var express = require('express'),
    server = express(),
    port = 3700,
    host = 'localhost',
    io = require('socket.io').listen(server.listen(port, host));

server
    .get('/', function(req, res){
        res.send('OK');
    });

io.sockets.on('connection', function(socket){
    console.log('connection started');

    // Update the server date every seconds
    setInterval(function(){
        socket.emit('date', {'date': new Date()});
    }, 1000);

    // Update locations every minutes
    setInterval(function(){
        console.log('Client: ' + socket.id);
        io.sockets.emit('update_locations', []);
    }, 1000);
});

io.sockets.on('disconnect', function(socket){
    console.log('Client "' + socket.id + '" disconnected');
});

See where I was looking to broadcast the update_locations message. I was investigating how I should perform the request to my API?

  • Am I doing it the right way?
  • Should I use http.get() in my setInterval() function?
  • Should I use setInterval()? I can't see how I would be able to do it without setInterval()

Cheer, Maxime

War es hilfreich?

Lösung

I'm answering my own question in details:

I'd like to thanks Lellansin to point me in the right direction:

Here is my server.js:

var express = require('express'),
    debug = true,
    http = require('http'),
    _ = require('underscore'),
    server = express(),
    port = 3700,
    api_host = 'api.acme.local',
    io = require('socket.io').listen(server.listen(port), {log: debug});


console.log('Node server listening on port', port);
io.set('log level', 1);

server
    .get('/', function(req, res){
        res.send('OK');
    });

var clients = {};

io.sockets.on('connection', function(socket){
    console.log('Client ' + socket.id + ' is connected');

    // Add the client to the list of connected clients
    clients[socket.id] = true;

    // Broadcast to everyone the list of connected clients
    io.sockets.emit('connected_clients', _.size(clients));

    // Send the current positions to the connected client when client is ready
    socket.on('ready', function() {
        getCourses(function(data){
            console.log('Send locations to client ' + socket.id);
            socket.emit('update_locations', data);
        });
    });

    // When a client is disconnecting, inform other clients
    socket.on('disconnect', function() {
        delete clients[socket.id];
        console.log('Client "' + socket.id + '" disconnected');
        io.sockets.emit('connected_clients', _.size(clients));
    });
});

// Update locations every minutes
setInterval(function()
{
    // Do nothing if there is no client
    if (_.size(clients) == 0) {
        return;
    }

    console.log('Update positions...');

    // Get the current courses and broadcast them to all clients
    getCourses(function(data){
        io.sockets.emit('update_locations', data);
    });
}, 60000); // every minute

// Update the server date every seconds
setInterval(function(){
    io.sockets.emit('date', {'date': new Date()});
}, 1000);


function getCourses(callback)
{
    var options = {
        hostname: api_host,
        port: 80,
        path: '/courses',
        method: 'GET'
    };

    var req = http.request(options, function(res) {
        //console.log('-----------------------------------------');
        //console.log('STATUS: ' + res.statusCode);
        //console.log('HEADERS: ' + JSON.stringify(res.headers));
        var output = '';

        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            output += chunk;
        });

        res.on('end', function() {
            var obj = JSON.parse(output);
            if (callback != undefined){
                callback(obj);
            }
        });
    });

    req.on('error', function(e) {
        console.log('problem with request: ' + e.message);
    });

    req.end();
}

I only broadcast the data if there is at least one client connected. I can't why it would not be a good idea but I'll appreciate any critics. Also it seems to me that it would start to be difficult to read if I'll have multiple API request on the server side.

Andere Tipps

io.sockets.emit means Broadcast to all, and your code means when there is a new connection you will get a new timer. If there is 100 connections, you will new 100*2 timers. My suggest code is below:

io.sockets.on('connection', function(socket){
    // signle connection

    var timer = setInterval(function(){
        // for signle
        io.sockets.socket(socket.id).emit( ... );

        // for all
        // io.sockets.emit( ... );
    }, 1000);

    // dont forget clear
    socket.on('disconnect', function() {
        clearInterval(timer)
    });
});

setInterval(function(){
    // emit for all connection
    io.sockets.emit( ... );
}, 1000);

hope it heplful.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top