2012-10-09 76 views
0

您好我正在編寫一個簡單的nodejs推送通知服務器,它基本上是讀取一個動態編輯的json文件並將其內容推送到客戶端。節點服務器在讀取由Python編輯的文件時崩潰

更新:它的工作,如果我刪除像data = JSON.parse(data);請問能澄清一下嗎?

我正在使用python每5秒編輯一次json文件。但是每次運行python循環來編輯文件時,節點服務器都會崩潰。但是,如果我分別在while循環內運行相同的代碼,則Node Server工作得很好。它如果工作:

我節點服務器

debug - cleared heartbeat timeout for client c_u5Oi1eGnwaDerGREMD 
    debug - set heartbeat interval for client c_u5Oi1eGnwaDerGREMD 
{"sample": {"name": "Shubhanshu Mishra100", "networks": ["facebook", "twitter", 
"linkedin"]}} 
    debug - websocket writing 5:::{"name":"notification","args":[{"sample":{"name 
":"Shubhanshu Mishra100","networks":["facebook","twitter","linkedin"]},"time":"2 
012-10-09T11:24:55.588Z"}]} 
{"sample": {"name": "Shubhanshu Mishra100", "networks": ["facebook", "twitter", 
"linkedin"]}} 
    debug - websocket writing 5:::{"name":"notification","args":[{"sample":{"name 
":"Shubhanshu Mishra100","networks":["facebook","twitter","linkedin"]},"time":"2 
012-10-09T11:24:55.589Z"}]} 
{"sample": {"name": "Shubhanshu Mishra200", "networks": ["facebook", "twitter", 
"linkedin"]}} 
    debug - websocket writing 5:::{"name":"notification","args":[{"sample":{"name 
":"Shubhanshu Mishra200","networks":["facebook","twitter","linkedin"]},"time":"2 
012-10-09T11:25:00.598Z"}]} 
{"sample": {"name": "Shubhanshu Mishra200", "networks": ["facebook", "twitter", 
"linkedin"]}} 
    debug - websocket writing 5:::{"name":"notification","args":[{"sample":{"name 
":"Shubhanshu Mishra200","networks":["facebook","twitter","linkedin"]},"time":"2 
012-10-09T11:25:00.619Z"}]} 


undefined:0 

^ 
SyntaxError: Unexpected end of input 
    at Object.parse (native) 
    at F:\My Codes\NodeJs\PushNotification\server.js:25:16 
    at fs.readFile (fs.js:176:14) 
    at Object.oncomplete (fs.js:297:15) 

我使用下面的代碼中的Node.js

io.sockets.on('connection', function(socket){ 
    fs.watch('response.json', function(curr, prev){ 
     fs.readFile('response.json', 'utf8', function(err, data){ 
      if(err) throw err; 
      console.log(data); 
      data = JSON.parse(data); 
      data.time = new Date(); 

      socket.volatile.emit('notification', data); 
     }); 

    }); 
}); 

UPDATE讀response.json文件收到以下錯誤我刪除了像data = JSON.parse(data);請問能澄清一下嗎?其中工程

我的Python代碼時,我調用我的Python腳本中的每個單獨是:

import json 
import time 

jsonStr = { 
    "sample": { 
     "name": "Shubhanshu Mishra", 
     "networks": [ 
       "facebook", 
       "twitter", 
       "linkedin" 
     ] 
    } 
} 

i = 0 
jsonStr['sample']['name'] = "Shubhanshu Mishra" + str(i); 
fStr = json.dumps(jsonStr) 
with open('response.json', 'w') as f: 
     f.write(fStr) 
f.closed 

然而,當我換行相同的代碼上面的while循環與我得到上述5秒的睡眠錯誤。我while循環代碼:

while True: 
    i += 100 
    print i 
    jsonStr['sample']['name'] = "Shubhanshu Mishra" + str(i); 
    fStr = json.dumps(jsonStr) 
    #f = open("response.json", "w") 
    with open('response.json', 'w') as f: 
     f.write(fStr) 
    f.closed 
    #f.write(fStr) 
    print "Written to file: " + fStr 
    #f.close() 
    time.sleep(5) 

我完整的代碼可以看出:https://github.com/napsternxg/PushNotification

回答

2

什麼情況是這樣的:Python的首先清除它,然後寫入字符串的文件寫入。一旦文件被清除,節點立即觸發事件並讀取(空)文件。然後,試圖JSON解析一個空字符串,你會得到錯誤。

問題是,爲什麼手動運行簡單的python腳本(不帶while循環)時不會發生這種情況。我不確定,但我認爲這與各種競爭條件有關,主要的區別在於,在循環中,在寫入文件之後,它打印一些東西,並睡眠一些,在另一個地方它只是退出。如果您爲手動免提腳本添加打印和睡眠,如果您遇到相同(崩潰)的行爲,我也不會感到驚訝。

那麼,如何解決這個問題。一個不那麼好,但工作方法是增加一個小的睡眠,讓寫來完成:

io.sockets.on('connection', function(socket){ 
    fs.watch('response.json', function(curr, prev){ 
     setTimeout(function() { 
     fs.readFile('response.json', 'utf8', function(err, data){ 
      if(err) throw err; 
      console.log(data); 
      data = JSON.parse(data); 
      data.time = new Date(); 

      socket.volatile.emit('notification', data); 
     }); 
     }, 50); 
    }); 
}); 

因爲我希望你從fs.watch得到2個回調,更好的將是通過下劃線去抖他們(實際上忽略第一個):

var _ = require("underscore"); 
io.sockets.on('connection', function(socket){ 
    fs.watch('response.json', _.debounce(function(curr, prev){ 
     fs.readFile('response.json', 'utf8', function(err, data){ 
      if(err) throw err; 
      console.log(data); 
      data = JSON.parse(data); 
      data.time = new Date(); 

      socket.volatile.emit('notification', data); 
     }), 50); 
    }); 
}); 

我認爲它甚至會工作像你期望你會忽略錯誤(因爲從fs.watch第二回調,該文件將包含正確的數據)。

但是,最後,我認爲這不是將新數據投射到正在運行的程序的方式。我會用下列方式之一:

  • 使用消息隊列系統
  • 使用命名管道上SIGHUP
  • 重裝configurationfiles(而不是當他們改變)
+0

感謝明確解釋, 你是我的英雄! –