在NodeJS服务器之间发送文件的最有效方式是什么?

介绍

说在同一个本地networking上,我们有两个使用Express设置的Node:JS服务器:服务器A用于API,服务器F用于表单。

  • 服务器A是一个API服务器,它接受请求并将其保存到MongoDB数据库(文件存储为缓冲区及其细节作为其他字段)
  • Server F服务表单,处理表单的邮件并将表单的数据发送到服务器A.

在接收服务器是Express API的两个NodeJS服务器之间发送文件的最有效的方法是什么? 文件大小在哪里?

1. HTTP方式

如果我发送的文件是PDF文件(不会超过50MB),通过HTTP将整个内容作为string发送是否有效?

algorithm如下:

  • 服务器F使用https://www.npmjs.com/package/multer处理文件请求并保存文件
  • 那么服务器F读取这个文件并通过https://github.com/request/request发出一个HTTP请求以及文件的一些细节
  • 服务器A收到这个请求,把文件内容从string转换成缓冲区,并在MongoDB中保存一个logging以及文件的详细信息。

在这个algorithm中,服务器A(当存储到MongoDB中)和服务器F(当它发送到服务器A时)已经将文件读入存储器,并且两个服务器之间的请求大小与文件大小相同。 (50Mb请求是否正确?)

然而,有一点需要考虑的是 – 使用这种方法 – 我将在整个过程中使用ExpressJS风格的API,并且与应用程序的其余部分保持一致,其中/list /details请求也在路线。 我喜欢一致性。

2. Socket.IO方式

与此algorithm相反,我已经探索了https://github.com/nkzawa/socket.io-stream方式,这与服务器A上的HTTP API的一致性脱节(因为socket.io事件的处理程序被定义不是在路由,但具有var server = http.createServer(app); )的文件。

服务器F在routes/some_route.js处理表单数据:

 router.post('/', multer({dest: './uploads/'}).single('file'), function (req, res) { var api_request = {}; api_request.name = req.body.name; //add other fields to api_request ... var has_file = req.hasOwnProperty('file'); var io = require('socket.io-client'); var transaction_sent = false; var socket = io.connect('http://localhost:3000'); socket.on('connect', function () { console.log("socket connected to 3000"); if (transaction_sent === false) { var ss = require('socket.io-stream'); var stream = ss.createStream(); ss(socket).emit('transaction new', stream, api_request); if (has_file) { var fs = require('fs'); var filename = req.file.destination + req.file.filename; console.log('sending with file: ', filename); fs.createReadStream(filename).pipe(stream); } if (!has_file) { console.log('sending without file.'); } transaction_sent = true; //get the response via socket socket.on('transaction new sent', function (data) { console.log('response from 3000:', data); //there might be a better way to close socket. But this works. socket.close(); console.log('Closed socket to 3000'); }); } }); }); 

我说我会处理<50Mb的PDF文件。 但是,如果将来使用此程序发送更大的文件,socket.io是处理1GB文件的更好方法,因为它正在使用stream?

这个方法确实发送了文件和细节,但是我对这个库不熟悉,不知道它是否应该用于这个目的,或者是否有更好的方法来利用它。

最后的想法

我应该探索什么替代方法?

  • 我是否应该通过SCP发送文件并发送一个包含文件详细信息的HTTP请求,从而将文件和API请求的协议分开?
  • 我应该总是使用stream,因为它们不存储整个文件到内存中? (这是他们的工作方式,对吧?)
  • 这个https://github.com/liamks/Delivery.js ?

参考文献:

  • 两个node.js服务器之间的文件/数据传输让我尝试套接字stream的方式。
  • 通过http方式在两个node.js服务器之间传输文件

有很多方法可以做到这一点,但没有太多要做到这一点!

套接字io和wesockets在浏览器中使用时效率很高,但是由于您不需要,所以不需要它。

你可以尝试的第一种方法是使用nodejs的内置Net模块,基本上它将在服务器之间build立一个tcp连接并传递数据。

你还应该记住,你需要发送数据块而不是整个文件,net模块的socket.write方法似乎很适合你的情况检查它: https : socket.write net.html

但是,根据文件的大小和并发性,内存消耗可能非常大。

如果你在两台服务器上运行linux,你甚至可以用一个简单的linux命令scp来发送文件

 nohup scp -rpC /var/www/httpdocs/* remote_user@remote_domain.com:/var/www/httpdocs & 

你甚至可以用windows到linux或者其他方式来做到这一点。

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html&#x4E0A;

Windows的客户端scp是pscp.exe

希望这可以帮助 !