標籤:blog http io ar os 使用 sp for 檔案
如果某個被請求的頁面資料比較大,或者是一個需要一定時間來完成的資料流,那麼以流的方式把已經完成的資料發送給用戶端是一個比較好的做法。在express中,一般的做法是等資料完成之後,統一發送,如使用exec執行系統命令時,之後在命令結束之後,才會調用回呼函數處理命令輸出。
- function cmd(command,req,callback) {
- var sys = require(‘sys‘)
- var exec = require(‘child_process‘).exec;
- console.log(new Date() + ‘ Run command from ‘ + req.ip);
- console.log(command);
- exec(command, {
- maxBuffer: 2000 * 1024
- }, function (error, stdout, stderr) {
- callback(stdout.trim());
- })
- }
以下的幾種方式可以用來實現流式的資料轉送。
持續寫res方式
最直白的方式就是持續寫入node的res對象,例如:
- var sys = require(‘sys‘),
- http = require(‘http‘);
- http.createServer(function (req, res) {
- res.writeHead(200, {‘Content-Type‘: ‘text/html‘});
- var currentTime = new Date();
- sys.puts(‘Starting sending time‘);
- setInterval(function(){
- res.write(
- currentTime.getHours()
- + ‘:‘ +
- currentTime.getMinutes()
- + ‘:‘ +
- currentTime.getSeconds() + "\n"
- );
- setTimeout(function() {
- res.end();
- }, 10000);
- },1000);
- }).listen(8090, ‘192.168.175.128‘);
但是這種方法的缺點很多,首先express架構中被封裝的res對象不支援這種方式的使用,更嚴重的是只有支援“XHR.readyState = 3 (partial response)”的瀏覽器才能這麼用。另外有人建議使用Sockets.io,有興趣的朋友可以試試。
- WebSocket
- WebSocket over Flash (+ XML security policy support)
- XHR Polling
- XHR Multipart Streaming
- Forever Iframe
- JSONP Polling (for cross domain)
使用stream對象的pipe
類似於 *nix 將幾乎所有裝置抽象為檔案一樣,Node 將幾乎所有 IO 操作都抽象成了 Stream 的操作。Stream 是一個抽象的概念,總之就是會冒資料(以 Buffer 為單位),或者能夠吸收資料的東西。
下面是上文系統命令執行的另一個例子,其中使用的spawn的stdout流:
- function cmd_stream(command,req,res) {
- console.log(new Date() + ‘ Run command stream from ‘ + req.ip);
- console.log(command);
- var spawn = require(‘child_process‘).spawn;
- var params = command.split(/\s+/);
- command = params.shift();
- var cmd_process = spawn(command,params);
- cmd_process.stderr.pipe(res);
- }
另一個檔案流pipe的例子:
- function file_stream(file,req,res) {
- console.log(new Date() + ‘ Run readfile stream from ‘ + req.ip);
- var fs = require(‘fs‘);
- var rstream = fs.createReadStream(‘/tmp/myfile‘);
- // var rstream = fs.createReadStream(file);
- rstream.pipe(res);
- }
Node.js 向用戶端發送流資料