이번에는 Node.js로 HTTP 파일 서버를 생성하는 단계에 대해 자세히 설명하겠습니다. Node.js로 HTTP 파일 서버를 생성할 때 주의사항은 무엇인가요? .
HelloWorld 예제는 데모 목적으로만 사용됩니다. 이번에는 파일 서버라는 실용적인 예제를 사용하겠습니다. Node.js를 사용하여 HTTP 프로토콜로 파일 서버를 생성합니다. 브라우저나 기타 다운로드 도구를 사용하여 파일 서버에서 파일을 다운로드할 수 있습니다.
파일을 읽으려면 파일 시스템 모듈("fs"라는 이름), Stream을 사용하고 URL도 분석하고 HTTP 메서드를 구별하며 EventEmitter를 사용합니다.
파일 서버 FileServer의 코드
코드부터 시작해 보겠습니다. 여전히 간단합니다.// 引入http模块 var http = require("http"); var fs = require("fs"); // 创建server,指定处理客户端请求的函数 http.createServer( function(request, response) { //判断HTTP方法,只处理GET if(request.method != "GET"){ response.writeHead(403); response.end(); return null; } //此处也可使用URL模块来分析URL(https://nodejs.org/api/url.html) var sep = request.url.indexOf('?'); var filePath = sep < 0 ? request.url : request.url.slice(0, sep); console.log("GET file: " + filePath); //当文件存在时发送数据给客户端,否则404 var fileStat = fs.stat("."+filePath, function(err, stats){ if(err) { response.writeHead(404); response.end(); return null; } //TODO:Content-Type应该根据文件类型设置 response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": stats.size}); //使用Stream var stream = fs.createReadStream("."+filePath); stream.on('data',function(chunk){ response.write(chunk); }); stream.on('end',function(){ response.end(); }); stream.on('error',function(){ response.end(); }); } ); } ).listen(8000); console.log("Hello World start listen on port 8000");
File System
FileSystem을 사용하려면 이전 코드와 마찬가지로 require를 사용하여 fs 모듈을 도입해야 합니다. 파일 시스템의 API는 오랫동안 사용되어 왔습니다. https://nodejs.org/api/fs.html을 살펴보세요. 우리는 사용된 기능에 대해서만 이야기합니다.파일 상태 가져오기
FileServer에서는 클라이언트 요청을 받으면 먼저 fs.stat() 메서드를 통해 파일 상태를 가져옵니다. fs.stat() 메소드 프로토타입은 다음과 같습니다:fs.stat(path, callback)
콜백 함수입니다. fs.stat() 메서드는 비동기식이며 콜백 함수 콜백을 통해 결과를 반환합니다. 콜백의 프로토타입은 다음과 같습니다.
function(err, stats)
HTTP 상태 코드를 200으로 설정하고, Content-Length 헤더도 설정합니다. 코드는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.
response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": stats.size} )ReadStream
다음으로 fs.createReadStream을 호출하여 ReadStream 객체를 생성합니다. ReadStream은 Stream이자 EventEmitter입니다. fs.createReadStream 메소드 프로토타입은 다음과 같습니다.fs.createReadStream(path[, options])
{ flags: ‘r', encoding: null, fd: null, mode: 0666, autoClose: true }
fs.createReadStream('sample.mp4', {start: 1000, end: 10000});
EventEmitter
Node.js基于V8引擎实现的事件驱动IO,是其最大最棒的特色之一。有了事件机制,就可以充分利用异步IO突破单线程编程模型的性能瓶颈,使得用JavaScript作后端开发有了实际意义。
EventEmitter的基本用法
events.EventEmitter是一个简单的事件发射器的实现,具有addListener、on、once、removeListener、emit等方法,开发者可以很方便的调用这些API监听某个事件或者发射某个事件。
我们在示例中用到的fs.ReadStream就是一个EventEmitter,它实现了stream.Readable接口,而stream.Readable具有data、error、end、close、readable等事件。
通常我们使用EventEmitter的on或addListener来监听一个事件,这个时间可能会多次触发,每次触发,我们提供的回调方法都会被调用。我们示例中的代码就是这样:
stream.on('data',function(chunk){ response.write(chunk); });
Node.js的事件机制,会给某个事件关联一个回调方法列表,这样多个关注者就可以监听同一个事件。每个事件发射时,可能会带有数据和状态,这些数据是通过回调方法的参数传递出来的。那某一个特定的事件,它对应的回调方法的参数是什么样子的,则由事件定义的那个类(实例)来决定。EventEmitter的emit方法原型如下:
emitter.emit(event[, arg1][, arg2][, ...])
这个原型说明一个事件的回调方法可以有一个或多个参数,也可以没有参数。要想知道某个事件的回调方法是否有参数、每个参数的含义,只好去找相关的API文档。stream.Readable的data事件的参数是chunk,Buffer类型,代表读到的数据。
如果我们只想监听某个事件一次,则可以调用EventEmitter的once方法。要想移除一个事件监听器,可以调用removeListener,想移除所有,则可以调用removeAllListener。
自定义事件
Node.js的很多模块都继承自Event模块。我们自己也可以通过继承EventEmitter来实现自己的对象,添加自己的自定义事件。
这里有个简单的例子:
var util=require("util"); var events = require("events"); function Ticker() { var self = this; events.EventEmitter.call(this); setInterval(function(){ self.emit("tick") }, 1000 ); } util.inherits(Ticker, events.EventEmitter); var ticker = new Ticker(); ticker.on("tick", function() { console.log("tick event"); });
在这个简单的例子里,我们定义了Ticker对象,通过全局方法setInterval开启了一个定时器,每隔1000毫秒发射一个名为“tick”的事件。
Node.js的工具模块封装了继承的方法,我们调用它来的inherits方法来完成Ticker对events.EventEmitter的继承。
自定义事件的使用方法,和Node.js内置模块提供的事件的用法完全一样。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 Node.js로 HTTP 파일 서버를 생성하는 단계에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!