简体   繁体   English

通过FTP从无服务器AWS Lambda发送二进制图像

[英]Send Binary Image from Serverless AWS Lambda Over FTP

I'm building an AWS Lambda API, using the serverless stack, that will receive an image as a binary string then store that image on GitHub and send it over FTP to a static app server. 我正在使用无服务器堆栈构建一个AWS Lambda API,它将接收图像作为二进制字符串,然后将该图像存储在GitHub上并通过FTP将其发送到静态应用服务器。 I am NOT storing the image in S3 at all as I am required not to. 我根本不将图像存储在S3中,因为我不需要这样做。

I have already figured out how to save the image to GitHub (by converting binary to base64), the issue is sending the binary image data over FTP to another server to hold statically. 我已经弄清楚了如何将图像保存到GitHub(通过将二进制文件转换为base64),问题是通过FTP将二进制图像数据发送到另一台服务器以静态保存。 The static image server is pre-existing and I cannot use S3. 静态图像服务器已存在,我无法使用S3。 I am using the ftp npm package to send the image. 我正在使用ftp npm软件包发送图像。 The image server indeed receives the image BUT NOT in the correct format and the image is just non-displayable junk data. 图像服务器确实接收到的不是正确格式的图像,而该图像只是不可显示的垃圾数据。 I saw an example on how to do this on the client side by encoding the image in an Uint16Array and passing it to a new Blob() object, but sadly, NODE.JS DOES NOT SUPPORT BLOBS! 我在客户端看到了一个有关如何通过在Uint16Array中对图像进行编码并将其传递到新的Blob()对象的示例,但是可悲的是,NODE.JS不支持球形!

Using ftp npm module: 使用ftp npm模块:

    async sendImage(image) {
        try {
            const credentials = await getFtpCredentials(this.platform);
            console.log('Sending files via FTP client');
            return new Promise((resolve, reject) => {
                let ftpClient = new ftp();
                ftpClient.on('ready', () => {
                    console.log(`Putting ${image.path} onto server`);
                    // Set transfer type to binary
                    ftpClient.binary(err => {
                        if(err)
                            reject(err);
                    });
                    // image.content is binary string data
                    ftpClient.put(image.content, image.path, (err) => {
                        if (err) {
                            reject(err);
                        }
                        console.log('Closing FTP connection');
                        ftpClient.end();
                        resolve(`FTP PUT for ${image.path} successful!`);
                    });
                });
                console.log('Connecting to FTP server');
                ftpClient.connect(credentials);
            });
        } catch(err) {
            console.log('Failed to load image onto FTP server');
            throw err;
        }
    }

This procedure sends the binary data to the server, but the data is un-readable by any browser or image viewer. 此过程将二进制数据发送到服务器,但是任何浏览器或图像查看器均无法读取该数据。 Do I need to use another FTP package? 我需要使用其他FTP软件包吗? Or am I just not encoding this right?? 还是我只是不编码这个权利? I've spent days googleing the answer to this seemingly common task and it's driving me up the wall! 我花了好几天的时间搜寻这个看似常见的任务的答案,这使我无所适从! Can anyone instruct me on how to send binary image data from a node.js lambda function over FTP to another server so that the image is encoded properly and works when viewed? 谁能指导我如何通过FTP从node.js lambda函数将二进制图像数据发送到另一台服务器,以使图像正确编码并在查看时可以工作? ANY help is very much appreciated! 很感谢任何形式的帮助!

So, it turns out that the ftp node module that I was using was the issue all along. 因此,事实证明,我一直使用的ftp节点模块一直都是问题。 It will corrupt any binary image transferred over FTP. 它将破坏通过FTP传输的任何二进制映像。 I submitted a ticket to the their GitHub repo, but they haven't made a commit in 4 years so I don't expect a timely fix. 我向他们的GitHub存储库提交了一张票,但是他们已经4年没有做出承诺了,所以我不希望及时解决。

To solve the problem, I used the Basic FTP package instead: 为了解决该问题,我改用了基本FTP软件包:

const ftp = require('basic-ftp');

async sendImage(image) {
    try {
        const { host, user, password } = await getFtpCredentials(this.platform);
        console.log('Received FTP credentials');
        console.log('Creating FTP client');
        const client = new ftp.Client();
        client.ftp.verbose = true;
        console.log('Logging in to remote server via FTP');
        await client.access({
            host, user, password, secure: false
        });
        console.log('Creating readable stream from binary data');
        const buffer = new Buffer(image.content, 'binary');
        const imgStream = new Readable();
        imgStream._read = () => {};
        imgStream.push(buffer);
        imgStream.push(null);
        console.log('Uploading readable stream to server via FTP');
        const result = await client.upload(imgStream, image.path);
        client.close();
        return result
    } catch(err) {
        console.log('Failed to load image onto FTP server');
        throw err;
    }
}

Note that this package requires data to be transferred via a Readable stream. 请注意,此程序包要求通过可读流传输数据。 Thanks to this SO answer, I learned how to convert a binary string to a Readable stream. 由于有了这个 SO答案,我学会了如何将二进制字符串转换为Readable流。 All works fine. 一切正常。

Happy coding! 编码愉快!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM