1

そのため、node.js で ajax を介してマルチパート フォーム アップローダーを構築し、進行状況イベントを socket.io を介してクライアントに送信して、アップロードのステータスを表示しています。複数のクライアントが同時にアップロードしようとするまで、すべてが正常に機能します。元々、1 つのアップロードが進行中のときに、2 番目のアップロードが開始されると、解析中の両方のフォームから進捗イベントを受信し始めます。元のフォームは影響を受けず、それ自体の進行状況の更新のみを受け取ります。新しい手ごわいフォームオブジェクトを作成し、それをソケットのセッションIDとともに配列に保存してこれを修正しようとしましたが、最初のフォームはイベントの受信を停止し、2番目のフォームは処理されます. ここに私のサーバーコードがあります:

var http        = require('http'),
formidable  = require('formidable'),
fs          = require('fs'), 
io          = require('socket.io'),
mime        = require('mime'),
forms       = {};

var server = http.createServer(function (req, res) {

if (req.url.split("?")[0] == "/upload") {
    console.log("hit upload");
    if (req.method.toLowerCase() === 'post') {
        socket_id = req.url.split("sid=")[1];
        forms[socket_id] = new formidable.IncomingForm();
        form = forms[socket_id];

        form.addListener('progress', function (bytesReceived, bytesExpected) {
            progress = (bytesReceived / bytesExpected * 100).toFixed(0);

            socket.sockets.socket(socket_id).send(progress);
        });

        form.parse(req, function (err, fields, files) {
            file_name = escape(files.upload.name);

            fs.writeFile(file_name, files.upload, 'utf8', function (err) {
                if (err) throw err;
                console.log(file_name);
            })
        });
    }
}
});

var socket = io.listen(server);
server.listen(8000);

誰かがこれについて何か助けになることができれば、私はそれを大いに感謝します. 私はこれを理解しようとして数日間自分の机に頭をぶつけていましたが、先に進むことができるようにこれを解決したいと思っています. よろしくお願いします!

4

2 に答える 2

0

入れてみませんかconsole.log(socket_id);

  1. form = forms[socket_id];
  2. progress = (bytesReceived / bytesExpected * 100).toFixed(0);、お願いします?

次のように、その socket_id をクロージャーでラップする必要があるかもしれないと感じています。

form.addListener(
  'progress', 
  (function(socket_id) {
    return function (bytesReceived, bytesExpected) {
        progress = (bytesReceived / bytesExpected * 100).toFixed(0);
        socket.sockets.socket(socket_id).send(progress);
    };
  })(socket_id)
);
于 2012-08-12T23:22:13.390 に答える
0

socket_id問題は、 andformをで宣言していないvarため、実際にはリクエスト ハンドラのローカル変数ではなくglobal.socket_idandであるということです。global.formその結果、コールバックが適切なクロージャーではなくグローバルを参照しているため、個別のリクエストが互いにステップオーバーします。

rdrey のソリューションは、その問題を回避するため機能します (ただし、socket_id参照されているコールバックの 1 つが問題を起こすような方法でコードを変更した場合のみform)。通常、問題の変数が外部関数の実行中に変化するものである場合にのみ、彼の手法を使用する必要があります (たとえば、ループ内でクロージャーを作成している場合)。

于 2012-08-13T04:20:35.363 に答える