使用socket.io将API从API广播到客户端

时间:2014-05-14 09:37:50

标签: node.js express socket.io

我不确定我想要实现的是正确的方法,因为我找不到任何例子。

我有一个显示Google地图和多个对象的应用程序。我希望每隔一秒或两秒自动更新对象的位置。

我在考虑让一个带有setInterval()的nodejs服务器每2秒触发一次,以便向不同的服务器执行API请求,获取数据响应并将其广播到所有socket.io客户端。 / p>

这是我目前正在使用的server.js

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');
});

查看我要播放update_locations消息的位置。 我正在研究如何对我的API执行请求?

  • 我是以正确的方式做到的吗?
  • 我应该在http.get()函数中使用setInterval()吗?
  • 我应该使用setInterval()吗?如果没有setInterval()
  • ,我无法理解如何做到这一点

欢呼, 马克西姆

2 个答案:

答案 0 :(得分:2)

我详细回答了我自己的问题:

我要感谢Lellansin指出我正确的方向:

这是我的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();
}

如果至少连接了一个客户端,我只会广播数据。我不能为什么这不是一个好主意,但我会感谢任何评论家。在我看来,如果我在服务器端有多个API请求,它将开始难以阅读。

答案 1 :(得分:1)

io.sockets.emit表示向所有人广播,而您的代码意味着当有新连接时,您将获得一个新计时器。如果有100个连接,您将获得新的100 * 2计时器。我建议的代码如下:

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);

希望它有益。