在node.js Hapi上大文件上传失败

时间:2017-11-29 14:24:26

标签: android node.js typescript upload hapijs

我有一个node.js脚本,它应该处理文件上传,同时也是多个。上传图片和声音工作得很好。但是,大约10 MB或更大的视频文件不会上传。有时它根本不起作用,有时会卡在fs.writeFile函数中。也许有更好的方式,因为我自己在代码中提出了很多部分。在磁盘上创建文件之前我需要md5哈希,因为它的路径将从哈希生成。另外我在Android端获得了SocketTimeoutException。 Code目前主要关注该部分,所以不要担心缺少输入验证和onProgress。

的NodeJS:

server.route({
method: 'POST',
path: '/uploadFile',
config: {
    payload: {
        output: 'stream',
        allow: 'multipart/form-data',
        maxBytes: 100*1024*1024 //100 mb

    }
}, handler: async function (request, reply)
{
    await incoming_uploadFile(request, reply);
}
});

...........

var joi = require('joi');
import { Paths } from "../util/Paths";
import * as fs from 'fs';

let data;
let numOfFiles: number;

export async function incoming_uploadFile(request, reply) {

data = request.payload;
await Application.InitializeSocket(null, "UploadFile");
let userID = await Application.AuthUser(JSON.parse(data['auth']));


numOfFiles = parseInt(data['numOfFiles']);


if (numOfFiles > 0)
    upload(0);

}

async function upload(i: number)
{


    const file = data['file' + i];
    const meta = data['fileMeta' + i];
    const metaJson = Application.StringToJson(meta);

    const fileType: string = metaJson['fileType'];
    const extension: string = metaJson['extension'];
    var crypto = require('crypto');

    const md5 = crypto.createHash('md5');

    var length = parseInt(file.hapi.headers["content-length"]);

    let buffer: Buffer = new Buffer(length);
    let bufPos : number = 0;
    file.on('data', function (b : Uint8Array) {
        for (var i = 0; i < b.byteLength; ++i)
            buffer.writeUInt8(b[i], bufPos++);

    });

    file.on('end', function (err) {

        var hash = md5.update(buffer.toString("base64")).digest("hex");
        const filePath: string = Paths.getFilePath(hash, fileType, extension);

        // Creates all dirs that are missing on the path
        var shell = require('shelljs');
        shell.mkdir('-p', require('path').dirname(filePath));

        console.log("writing buffer to file...");

        fs.writeFile(filePath, buffer,null);

        if ((++i) < numOfFiles)
            upload(i);




    });

}

Android上传文件:

 public static void uploadAttachments(ArrayList<EventAttachment> attachments)
{

    OkHttpClient client = new OkHttpClient();
    // Add attachments
    MultipartBody.Builder builder = new MultipartBody.Builder();
    builder.setType(MultipartBody.FORM);
    builder.addFormDataPart("numOfFiles",String.valueOf(attachments.size()));

    for (int i = 0; i < attachments.size();++i) {
        EventAttachment attachment = attachments.get(i);
        File file = new File(attachment.getPath());
        String extension = MimeTypeMap.getFileExtensionFromUrl(attachment.getPath());
        String type = null;
        if (extension != null) {
            type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
        } else {

            Log.e("x", "Could not get extensions of file " + file.getAbsolutePath() + ". File upload aborted.");
            return;
        }

        ProgressRequestBody p = new ProgressRequestBody(RequestBody.create(MediaType.parse(type), file), new ProgressRequestBody.Listener() {
            @Override
            public void onProgress(int progress) {

            }
        });

        builder.addFormDataPart("file" + i, file.getName(), p);
        HashMap<String, String> hm = new HashMap<>();
        hm.put("extension", extension.replace(".", ""));
        hm.put("fileType", String.valueOf(attachment.getType()));
        builder.addFormDataPart("fileMeta" + i, new JSONObject(hm).toString());


    }
    JSONObject jObj = new JSONObject();
        builder.addFormDataPart("auth", putDefaultHeader(jObj).toString());
        MultipartBody mb = builder.build();


        okhttp3.Request request = new Request.Builder().url(EndPoint+UPLOAD_FILE).post(mb).build();


        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

                Log.e("x", "Error uploading file");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });





}

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

已添加

timeout: false, parse: true

在配置有效负载上,现在可以使用。

相关问题