0

こんにちは、基本的に動的に編集されたjsonファイルを読み取り、そのコンテンツをクライアントにプッシュする単純なnodejsプッシュ通知サーバーを作成しています。

更新: like data = JSON.parse(data); を削除すると機能します。誰でも明確にできますか?

5秒ごとにpythonを使用して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で次のコードを使用してresponse.jsonファイルを読んでいます

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

    });
});

更新: like 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

ただし、上記の同じコードを 5 秒のスリープで while ループでラップすると、上記のエラーが発生します。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 で見ることができます。

4

1 に答える 1

2

何が起こるか: Python は、最初にファイルをクリアしてから文字列を書き込むことで、ファイルを書き込みます。ノードは、ファイルがクリアされるとすぐにイベントを発生させ、(空の) ファイルを読み取ります。次に、空の文字列を JSON で解析しようとすると、エラーが発生します。

問題は、単純な python スクリプト (while ループなし) を手動で実行すると、なぜこれが起こらないのかということです。よくわかりませんが、これはあらゆる種類の競合状態に関係していると考えています。主な違いは、ファイルへの書き込み直後のループで、いくつかのものを出力し、いくつかをスリープさせます。単に終了する場合。print と sleep を手動の while-free スクリプトにも追加した場合に、同じ (クラッシュ) 動作が発生しても、まったく驚かないでしょう。

では、これを解決する方法。あまり良い方法ではありませんが、書き込みを終了できるように、小さなスリープを追加することが有効な方法です。

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

から 2 つのコールバックを取得すると予想fs.watchされるため、アンダースコアを介してそれらをデバウンスする方が適切です (実際には、最初のコールバックは無視されます)。

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

エラーを無視すれば、期待どおりに動作すると思います (からの 2 番目のコールバックfs.watchで、ファイルには正しいデータが含まれるため)。

ただし、最終的には、これは実行中のプログラムに新しいデータを送信する方法ではないと主張します。次のいずれかの方法を使用します。

  • メッセージ キュー システムを使用する
  • 名前付きパイプを使用する
  • sighup 時に設定ファイルをリロードします (変更時ではありません)。
于 2012-10-09T17:09:15.470 に答える