2013-10-01 10 views
0

我有一個node.js服務器打開8000端口。它是一個聊天服務器。 我有另一個PHP服務器,我使用代理+虛擬主機,所以當我去www.phpserver.com/chat它代理到node.js服務器。我這樣做,所以我可以使用ajax來調用node.js服務器。Node.js服務器發回EOF塊PHP服務器

現在,一切正常,當我運行node.js服務器,但是,一段時間後(隨機時間框架,不一定是長或短),PHP服務器將粉碎,因爲它從節點獲取EOF .js服務器,它只是停留在那裏,直到我停止/重新啓動node.js服務器。

我得到錯誤的是(從PHP錯誤日誌):

(70014)找到文件的結束:從遠程服務器 nodeserver.com:8000,引薦錯誤讀取狀態行:代理https://www.phpserver.com

我問了一些專業人士,他們說這是因爲PHP服務器成功發送請求到node.js服務器並收到EOF或未能收到任何響應。我不明白如何解決這個問題。我應該怎麼做,即使node.js服務器崩潰,它不會粉碎PHP服務器?我應該擺脫代理+ Ajax,並開始使用socket.io?

請指教。

謝謝!


下面是一些節點代碼。

從中間件:

 this.events.addListener('update', o_.bind(function(package) { 
    if(this.clear != 0){ 
    delete this.sessions[this.clear]; 
    } 
     var _package = package.toJSON(); 
     if(package.type == 'status' && package.status == 'offline') { 
      var sids = Object.keys(this.sessions), sid, sess; 
      for(sid in this.sessions) { 
       sess = this.sessions[sid]; 
       if(sess.data('username') == package.username) { 
        if(sess.listeners.length) 
         sess.send(200, {type: 'goodbye'}); 
        delete this.sessions[sid]; 
        break; 
       } 
      } 
     } 
    }, this)); 
}; 

Hub.prototype.destroy = function(sid, fn) { 
    this.set(sid, null, fn); 
}; 

Hub.prototype.reap = function(ms) { 
    var threshold = +new Date - ms, 
     sids = Object.keys(this.sessions); 
    for(var i = 0, len = sids.length; i < len; ++i) { 
     var sid = sids[i], sess = this.sessions[sid]; 
     if(sess.lastAccess < threshold) { 
     this.events.emit('update', new packages.Offline(sess.data('username'))); 
     } 
    } 
}; 


Hub.prototype.get = function(req, fn) { 
    if(this.sessions[req.sessionID]) { 
     fn(null, this.sessions[req.sessionID]); 
    } else { 
     this.auth.authenticate(req, o_.bind(function(data) { 
      if(data) { 
       var session = new User(req.sessionID, data); 
       this.set(req.sessionID, session); 

       this.auth.friends(req, data, o_.bind(function(friends) { 
        var friends_copy = friends.slice(); 
        o_.values(this.sessions).filter(function(friend) { 
         return ~friends.indexOf(friend.data('username')); 
        }).forEach(function(friend) { 
         var username = friend.data('username'); 
         friends_copy[friends_copy.indexOf(username)] = 
              [username, friend.status()]; 
        }, this); 

        session._friends(friends_copy); 
      console.log("refreshed"); 
        session.events.addListener('status', 
         o_.bind(function(value, message) { 
          this.events.emit(
           'update', 
           new packages.Status(session.data('username'), 
                value, 
                message) 
          ); 
         }, this)); 
        this.events.addListener('update', 
             o_.bind(session.receivedUpdate, session)); 
        this.set(req.sessionID, session); 
        fn(null, session); 
       }, this)); 
      } else { 
       fn(); 
      } 
     }, this)); 
    } 
}; 

從app.js

#!/usr/bin/env node 
var sys = require('sys'), 
    express = require('express'), 
    packages = require('./libs/packages'), 
    fs = require('fs'), 
    o_ = require('./libs/utils'), 
    https = require('https'); 

o_.merge(global, require('./settings')); 
try { o_.merge(global, require('./settings.local')); } catch(e) {} 

try { 
    var daemon = require('./libs/daemon/daemon'), 
     start = function() { 
      daemon.init({ 
       lock: PID_FILE, 
       stdin: '/dev/null', 
       stdout: LOG_FILE, 
       stderr: LOG_FILE, 
       umask: 0, 
       chroot: null, 
       chdir: '.' 
      }); 
     }, 
     stop = function() { 
      process.kill(parseInt(require('fs').readFileSync(PID_FILE))); 
     }; 

    switch(process.argv[2]) { 
     case 'stop': 
      stop(); 
      process.exit(0); 
     break; 

     case 'start': 
      if(process.argv[3]) 
       process.env.EXPRESS_ENV = process.argv[3]; 
      start(); 
     break; 

     case 'restart': 
      stop(); 
      start(); 
      process.exit(0); 
     break; 

     case 'help': 
      sys.puts('Usage: node app.js [start|stop|restart]'); 
      process.exit(0); 
     break; 
    } 
} catch(e) { 
    sys.puts('Daemon library not found! Please compile ' + 
      './libs/daemon/daemon.node if you would like to use it.'); 
} 
var options = { 
    key: fs.readFileSync('/home/ec2-user/key.pem'), 
    cert: fs.readFileSync('/home/ec2-user/cert.pem'), 
    ca: fs.readFileSync('/home/ec2-user/ca.pem'), 
}; 

var app = express(); 

//app.set('env', 'development'); 
app.use(express.methodOverride()); 
app.use(express.cookieParser()); 
app.use(express.bodyParser()); 
app.use(require('./middleware/im')({ 
    maxAge: 30 * 1000, 
    reapInterval: 20 * 1000, 
    authentication: require('./libs/authentication/' + AUTH_LIBRARY) 
})); 

app.set('root', __dirname); 

if ('development' == app.get('env')) { 
    app.set('view engine', 'jade'); 
    app.set('views', __dirname + '/dev/views'); 

    app.stack.unshift({ 
     route: '/dev', 
     handle: function(req, res, next) { 
      req.dev = true; 
      next(); 
     } 
    }); 

    app.use(express.logger()); 
    require('./dev/app')('/dev', app); 
    app.use(express.static(
       require('path').join(__dirname, '../client'))); 
    app.use(express.errorHandler({dumpExceptions: true, showStack: true})); 
} 

//app.listen(APP_PORT, APP_HOST); 

// Listener endpoint; handled in middleware 
app.get('/listen', function(){}); 

app.post('/message', function(req, res) { 
    res.find(req.body['to'], function(user) { 
     if(!user) 
      return res.send(new packages.Error('not online')); 

     res.message(user, new packages.Message(
      req.session.data('username'), 
      req.body.body 
     )); 
    }); 
}); 

app.post('/message/typing', function(req, res) { 
    if(~packages.TYPING_STATES.indexOf('typing' + req.body['state'])) { 
     res.find(req.body['to'], function(user) { 
      if(user) { 
       res.message(user, new packages.Status(
        req.session.data('username'), 
        'typing' + req.body.state 
       )); 
      } 

      // Typing updates do not receive confirmations, 
      // as they are not important enough. 
      res.send(''); 
     }); 
    } else { 
     res.send(new packages.Error('invalid state')); 
    } 
}); 

app.post('/status', function(req, res) { 
    if(~packages.STATUSES.indexOf(req.body['status'])) { 
     res.status(req.body.status, req.body.message); 
     res.send(new packages.Success('status updated')); 
    } else { 
     res.send(new packages.Error('invalid status')); 
    } 
}); 


app.post('/online', function(req, res) { 
var d = new Date(); 
var n = d.getTime() + 30; 
req.sessionID.expires = n; 
res.status(req.body.status, 'available'); 
}); 


app.post('/signoff', function(req, res) { 
    res.signOff(); 
    res.send(new packages.Success('goodbye')); 
}); 


app.use(function(err, req, res, next){ 
    console.error(err.stack); 
    res.send(500, 'Error on the node/express server.'); 
}); 


https.createServer(options, app).listen(8000); 

回答

0

我不能幫你回答你的問題,但我可以嘗試爲你指明一個正確的方向。

我目前正在自己​​的Node JS服務器上工作,而且我發現非常有用的有一個記錄器設置。

有一些,但我最喜歡的是溫斯頓迄今。

參考:https://github.com/flatiron/winston

要安裝溫斯頓爲您節點JS服務器(好像你已經安裝了幾個模塊):

npm install winston 

然後,我有記錄模塊設置爲(logger.js ):

/** 
* Usage: 
* - logger.info('sample text'); 
* - logger.warn('sample text'); 
* - logger.error('sample text'); 
*/ 

// Load modules 
var winston = require('winston'); 

// Create custom logger 
var logger = new (winston.Logger)({ 
    transports: [ 
     new (winston.transports.Console)({ json: false, timestamp: true }), 
     new winston.transports.File({ filename: __dirname + '/debug.log', json: false }) 
    ], 
    exceptionHandlers: [ 
     new (winston.transports.Console)({ json: false, timestamp: true }), 
     new winston.transports.File({ filename: __dirname + '/exceptions.log', json: false }) 
    ], 
    exitOnError: false 
}); 

// Export logger 
module.exports = logger; 

最後,我將溫斯頓記錄器模塊加載到我的服務器腳本中:

var logger = require('./logger'); 

它會自動記錄任何異常轉換成exceptions.log您節點JS服務器位置。它幫助我在Node中與PHP無關的異常中捕獲到我沒有注意到的異常。

P.S.另外檢查一下socket.io,這可能會簡化你正在嘗試做的事情。

+0

嗨,謝謝,我在另一個通知中心使用了socket.io。我必須解決這個問題,因爲即使當我使用socket.io時,一些用戶仍然可能會遇到這個問題,因爲並非所有的瀏覽器都支持WebSocket。而現在,當這個問題發生時,整個服務器被凍結並且永遠等待來自node.js服務器的響應,意味着沒有人可以訪問任何頁面......非常感謝日誌記錄。 – jackhao

+0

我最近注意到的另一件事是,在某些客戶端連接和重新連接以及節點js服務器重新啓動的情況下,連接上會出現乘法。基本上客戶端和服務器將獲得發射器上的多個數據。我通過時間戳檢查重複的消息來解決這個問題。這使我的服務器變得非常嚴重。如果您跟蹤節點js服務器中連接的客戶端,請檢查它們中是否有任何發送重複的消息。 – Rigganator