text: //引入express
  var express = require('express'),
      async = require('async'),
      pg = require("pg"),
      cookieParser = require('cookie-parser'),
      bodyParser = require('body-parser'),
      methodOverride = require('method-override'),
      //启动服务
      app = express(),
      server = require('http').Server(app),
      io = require('socket.io')(server);
  
  io.set('transports', ['polling']);
  
  var port = process.env.PORT || 4000;
  
  io.sockets.on('connection', function (socket) {
  
    socket.emit('message', { text : 'Welcome!' });
  
    socket.on('subscribe', function (data) {
      socket.join(data.channel);
    });
  });
  
  // async异步控制，times表示重试次数，interval表示重试间隔，callback是retry的回调函数
  async.retry(
    {times: 1000, interval: 1000},
    function(callback) {
      // 连接postgresql
      pg.connect('postgres://postgres@db/postgres', function(err, client, done) {
        if (err) {
          console.error("Waiting for db");
        }
        callback(err, client);
      });
    },
    function(err, client) {
      if (err) {
        return console.err("Giving up");
      }
      console.log("Connected to db");
      getVotes(client);
    }
  );
  
  function getVotes(client) {
    client.query('SELECT vote, COUNT(id) AS count FROM votes GROUP BY vote', [], function(err, result) {
      if (err) {
        console.error("Error performing query: " + err);
      } else {
        var votes = collectVotesFromResult(result);
        //表示发送了一个action命令和data数据，命令是字符串。
        io.sockets.emit("scores", JSON.stringify(votes));
      }
      // 用于在指定的毫秒数后调用函数
      setTimeout(function() {getVotes(client) }, 1000);
    });
  }
  
  function collectVotesFromResult(result) {
    var votes = {a: 0, b: 0};
  
    result.rows.forEach(function (row) {
      votes[row.vote] = parseInt(row.count);
    });
  
    return votes;
  }
  
  app.use(cookieParser());
  app.use(bodyParser());
  app.use(methodOverride('X-HTTP-Method-Override'));
  app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
    next();
  });
  
  app.use(express.static(__dirname + '/views'));
  
  app.get('/', function (req, res) {
    res.sendFile(path.resolve(__dirname + '/views/index.html'));
  });
  
  //监听端口
  server.listen(port, function () {
    var port = server.address().port;
    console.log('App running on port ' + port);
  });
  