1. 程式人生 > >NodeJs實現一個簡易的WEB上傳下載伺服器

NodeJs實現一個簡易的WEB上傳下載伺服器

專案上的需求是叢集均可生成PDF檔案或是訪問PDF檔案,但是沒有檔案伺服器,故做一個簡易的檔案伺服器。

解決方案:叢集內的機器(客戶端)生成PDF檔案之後將PDF檔案推給檔案伺服器,我們暫且稱它為服務端;如果某個客戶端需要訪問到這個PDF檔案,則去服務端獲取(因為可能其他客戶端已經生成了該PDF檔案),如果沒有找到,則自己客戶端生成PDF檔案,再將PDF檔案推給服務端。

為了實施簡易,現採取NodeJs來實現一個小程式。 不多說,直接上程式碼...

server.js

var express = require('express');
var url = require('url');
var fs = require('fs');
var http = require('http');
var queryString = require('querystring');
var bodyParser = require('body-parser');
var path=require('path'); 

var app = express();

app.use(bodyParser.json({limit:'1000kb'}));
app.use(bodyParser.urlencoded({limit:'1000kb',extended:true}));

var count=0;

app.post('/upload.node',function(req,resp){
	console.log('上傳請求 '+ (new Date()));
	var data = new Buffer(req.body.fileData,'base64');
	var filePath = req.body.filePath;
	var pathObj = path.parse(filePath);//對檔案路徑字串進行操作
	
	var responseBody = {};
	mkdirsSync(pathObj.dir);//遞迴建立檔案目錄
	try{
		var writerStream = fs.createWriteStream(filePath);
		writerStream.write(data);	
		writerStream.end();
		
		writerStream.on('finish', function() {
			console.log('上傳完成 '+ (new Date()));
		});
		writerStream.on('error', function(err){
			console.log(err.stack);
		});
		responseBody=JSON.stringify({
			returnMsg:'200'
		});
	}catch(err){
		console.log('上傳出錯 '+ (new Date()));
		responseBody=JSON.stringify({
			returnMsg:'400'
		});
	}
	//寫入檔案
	
	//console.log('*** ' + count +' ***');
    resp.status(200).end(responseBody.toString());
});

app.post('/download.node',function(req,resp){
	console.log('下載請求 '+ (new Date()));
	var filePath = req.body.filePath;
	console.log('download');
	var responseBody = {};
	if(fs.existsSync(filePath)){
		var data = fs.readFileSync(filePath);
		var dataBase64 = data.toString('base64');
		responseBody = JSON.stringify({
			returnMsg:'200',
			filePath:filePath,
			fileData:dataBase64
		});
		console.log('下載完成 '+ (new Date()));
	}else{
		responseBody=JSON.stringify({
			returnMsg:'400'
		});
		console.log('檔案未找到 '+ (new Date()));
	}
	//console.log('*** ' + ++count +' ***');
	resp.status(200).end(responseBody.toString());
});

//遞迴建立檔案目錄 同步方法
function mkdirsSync(filePath){
	if(fs.existsSync(filePath)){
		return true;
	}else{
		if(mkdirsSync(path.dirname(filePath))){
			fs.mkdirSync(filePath);
			return true;
		}
	}
}


var server = app.listen(20001,function(){
	
	console.log('Server started.');
})

提供一個測試js程式碼..  瀏覽器通過get請求 http://127.0.0.1:20000/upload.do?filePath=XXXX即可觸發上傳過程

var express = require('express');
var url = require('url');
var fs = require('fs');
var http = require('http');
var queryString = require('querystring');
var bodyParser = require('body-parser');

var app = express();

app.use(bodyParser.json({limit:'1000kb'}));
app.use(bodyParser.urlencoded({limit:'1000kb',extended:true}));

var count=0;

app.get('/upload.do',function(req,resp){
	console.log('upload.do');
	//var path = url.parse(req.url).pathname;
	//console.log('Request for ' + path);
	var filePath = req.query.filePath;
	//var fileData = req.query.fileData;
	var address = req.query.address;
	
	upload(filePath,'127.0.0.1',20001);
	console.log('*** ' + ++count +' ***');
	var response = {
       "first":req.query.filePath,
       "last":req.query.address
   };
   resp.end(JSON.stringify(response));
});

function upload(filePath,address,port){
	
	var Data = readFile(filePath);
	var dataBase64 = Data.toString('base64');
	console.log(Data);
	console.log(dataBase64);
	//var DataJSON = JSON.stringify(Data);
	
	//fs.writeFile('D:/input.txt',dataBase64,function(err){
	//	if(err){
	//		console.err(err);
	//	}
	//});
	var JsonData = queryString.stringify({
		filePath:filePath,
		fileData:dataBase64
	});
	//console.log(JsonData);
	var options = {
		method: "POST",
		host : address,
		port : port,
		path : '/upload.node',
		headers: {
			'Content-Type':'application/x-www-form-urlencoded'
		}
	};
	
  var req = http.request(options, function(res){
	  res.setEncoding('utf8');
  });
  req.write(JsonData);
  req.end();
}

function readFile(filePath){
	var fileData = '';
	try{
		fileData = fs.readFileSync(filePath);
	}catch(e){
		fileData = '';
	}
	return fileData;
}

app.post('/download.do',function(req,resp){
	//可直接參考server.js的程式碼
})

var server = app.listen(20000,function(){
	
	console.log('Server started.');
})

這僅僅是一個簡易的Nodejs程式,直接用此程式去壓測,得到結果是每秒可處理八十多個請求,基本上能滿足現在的需求,還有很多改進的地方,比如加入快取,佇列....等等。

對於NodeJs本人也只是學到了一點皮毛,還有很多知識點沒去探究。大家看看就行。