javascript - Node.js 强大的文件上传在服务器上运行缓慢

标签 javascript angularjs node.js nginx pm2

我正在尝试使用 angular.js 中的 http post 请求将文件作为表单数据以及一些字段发送,并在 node.js 中的 app.post 中接收文件。文件发送在本地主机上工作正常。正如他们所说,强大的上传文件速度为 500 mb/秒,但在服务器上,当我尝试发送 5 到 10 mb 的文件时,需要 40 到 80 秒。请检查我的实现是否有问题。 我在服务器上使用 nginx 和 pm2。

Node.js 代码:

// route for uploading audio asynchronously
app.post('/v1/uploadAudio', function(req, res) {
    var userName, useravatar, hasfile, ismusicfile, isType, showMe, DWimgsrc, DWid, msgtime;
    var imgdatetimenow = Date.now();
    var form = new formidable.IncomingForm({
        uploadDir: __dirname + '/public/app/upload/music',
        keepExtensions: true
    });


    form.on('end', function() {
        res.end();
    });
    form.parse(req, function(err, fields, files) {
        console.log("files : ", files);
        console.log("fields : ", fields);
        var data = {
            username: fields.username,
            userAvatar: fields.userAvatar,
            repeatMsg: true,
            hasFile: fields.hasFile,
            isMusicFile: fields.isMusicFile,
            istype: fields.istype,
            showme: fields.showme,
            dwimgsrc: fields.dwimgsrc,
            dwid: fields.dwid,
            serverfilename: baseName(files.file.path),
            msgTime: fields.msgTime,
            filename: files.file.name,
            size: bytesToSize(files.file.size)
        };
        var audio_file = {
            dwid: fields.dwid,
            filename: files.file.name,
            filetype: fields.istype,
            serverfilename: baseName(files.file.path),
            serverfilepath: files.file.path,
            expirytime: imgdatetimenow + (120000)
        };
        files_array.push(audio_file);
        ios.sockets.emit('new message music', data);
    });
});

AngularJS 代码:

// =========================================== Audio Sending Code =====================
$scope.$watch('musicFiles', function() {
    $scope.sendAudio($scope.musicFiles);
});

//  opens the sent music file on music_icon click on new window
$scope.openClickMusic = function(msg) {
    $http.post($rootScope.baseUrl + "/v1/getfile", msg).success(function(response) {
        if (!response.isExpired) {
            window.open($rootScope.baseUrl + '/' + response.serverfilename, "_blank");
        } else {
            var html = '<p id="alert">' + response.expmsg + '</p>';
            if ($(".chat-box").has("p").length < 1) {
                $(html).hide().prependTo(".chat-box").fadeIn(1500);
                $('#alert').delay(1000).fadeOut('slow', function() {
                    $('#alert').remove();
                });
            }
        }
    });
}

// recieving new music message
$socket.on("new message music", function(data) {
    if (data.username == $rootScope.username) {
        data.ownMsg = true;
        data.dwimgsrc = "app/images/spin.gif";
    } else {
        data.ownMsg = false;
    }
    if ((data.username == $rootScope.username) && data.repeatMsg) {
        checkMessegesMusic(data);
    } else {
        $scope.messeges.push(data);
    }
});

// replacing spinning wheel in sender message after music message delivered to everyone.
function checkMessegesMusic(msg) {
    for (var i = ($scope.messeges.length - 1); i >= 0; i--) {
        if ($scope.messeges[i].hasFile) {
            if ($scope.messeges[i].istype === "music") {
                if ($scope.messeges[i].dwid === msg.dwid) {
                    $scope.messeges[i].showme = true;
                    $scope.messeges[i].serverfilename = msg.serverfilename;
                    $scope.messeges[i].filename = msg.filename;
                    $scope.messeges[i].size = msg.size;
                    $scope.messeges[i].dwimgsrc = "app/images/musicplay_icon.png";
                    break;
                }
            }
        }
    };
}

// download music file if it exists on server else return error message
$scope.downloadMusic = function(ev, elem) {
    var search_id = elem.id;
    for (var i = ($scope.messeges.length - 1); i >= 0; i--) {
        if ($scope.messeges[i].hasFile) {
            if ($scope.messeges[i].istype === "music") {
                if ($scope.messeges[i].dwid === search_id) {
                    $http.post($rootScope.baseUrl + "/v1/getfile", $scope.messeges[i]).success(function(response) {
                        if (!response.isExpired) {
                            var linkID = "#" + search_id + "A";
                            $(linkID).find('i').click();
                            return true;
                        } else {
                            var html = '<p id="alert">' + response.expmsg + '</p>';
                            if ($(".chat-box").has("p").length < 1) {
                                $(html).hide().prependTo(".chat-box").fadeIn(1500);
                                $('#alert').delay(1000).fadeOut('slow', function() {
                                    $('#alert').remove();
                                });
                            }
                            return false;
                        }
                    });
                    break;
                }
            }
        }
    };
}

// validate file type to 'music file' function
$scope.validateMP3 = function(file) {
    if (file.type == "audio/mp3" || file.type == "audio/mpeg") {
        return true;
    } else {
        var html = '<p id="alert">Select MP3.</p>';
        if ($(".chat-box").has("p").length < 1) {
            $(html).hide().prependTo(".chat-box").fadeIn(1500);
            $('#alert').delay(1000).fadeOut('slow', function() {
                $('#alert').remove();
            });
        }
        return false;
    }
}

// sending new 'music file' function
$scope.sendAudio = function(files) {
    if (files && files.length) {
        $scope.isFileSelected = true;
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            var dateString = formatAMPM(new Date());
            var DWid = $rootScope.username + "dwid" + Date.now();
            var audio = {
                username: $rootScope.username,
                userAvatar: $rootScope.userAvatar,
                hasFile: $scope.isFileSelected,
                isMusicFile: true,
                istype: "music",
                showme: false,
                dwimgsrc: "app/images/musicplay_icon.png",
                dwid: DWid,
                msgTime: dateString
            }

            $socket.emit('send-message', audio, function(data) { // sending new image message via socket
            });
            var fd = new FormData();
            fd.append('file', file);
            fd.append('username', $rootScope.username);
            fd.append('userAvatar', $rootScope.userAvatar);
            fd.append('hasFile', $scope.isFileSelected);
            fd.append('isMusicFile', true);
            fd.append('istype', "music");
            fd.append('showme', false);
            fd.append('dwimgsrc', "app/images/musicplay_icon.png");
            fd.append('dwid', DWid);
            fd.append('msgTime', dateString);
            fd.append('filename', file.name);
            $http.post('/v1/uploadAudio', fd, {
                transformRequest: angular.identity,
                headers: {
                    'Content-Type': undefined
                }
            }).then(function(response) {
                // console.log(response);
            });
        }
    }
};

最佳答案

我在几个业余项目中使用了 Formidable,当上传到本地主机时,我确实看到了 500mb/秒的引用能力(取决于计算机的物理硬件)。

但是,通过互联网上传文件时,您会受到 ISP 上传速度以及服务器下载速度的带宽限制。

您报告说,一个 10MB 的文件上传到服务器大约需要 80 秒。这大约是 125KBps(或大约 1 兆位/秒),这对于家庭/办公室 ISP 上传速度来说似乎相当合理(取决于世界地区)。

从故障排除等式中消除家庭/办公室网络性能的一个好方法是编写一个 Node.js 脚本,该脚本多次上传文件并计算平均速度。在本地计算机上运行该测试文件,然后从云中的其他服务器重试。

关于javascript - Node.js 强大的文件上传在服务器上运行缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31692284/

相关文章:

javascript - 如何获取div拖动后的起始值和结束值

javascript - SAPUI5 JS 用 OR 组合多个过滤器

javascript - 切换图例可见性时,highcharts 堆叠列重叠

javascript - 怎样才能让这个功能更加高效呢?

javascript - Javascript 与 Google Dart 的比较

javascript - 如何在 Node js 中创建日志文件并获取 502 错误?

javascript - Angular : is it possible to pass an array or multiple strings to the $on event listener so as not to have multiple lines of listeners?

javascript - 如何在 ExtJS 面板中使用 jQuery 脚本

javascript - Angular ui-bootstrap datepicker更改主题

c++ - 如何将 C++ 类返回到 NODE.JS