node介绍

2018-11-24  本文已影响0人  wish_dd

node 特点

创建一个Server

'use strict';
const http = require('http');
http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type':'text/html; charset= UTF-8; '});
    res.end('Hello World!');
}).listen(8080);

➜  ~ curl 127.0.0.1:8080
Hello World!%

这就是一个最简单的helloWorld,那我们客户端请求到server是如何运行的呢?

1.http模块在node 中http模块有2个一个是http-client,一个是http-server
2.http模块是继承与net模块,net模块是继承与events
3.events只提供了 events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装
4.此时的http就拥有了事件的监听与触发功能

实现原理

我们通过代码http.createServer方法

// http.js
function createServer(opts, requestListener) {
  return new Server(opts, requestListener);
}
//http-server.js
function Server(options, requestListener) {
    /*省略代码*/
  if (requestListener) {
    this.on('request', requestListener);  
  }
  this.on('connection', connectionListener);
}

核心代码是注册了2个方法一个request,一个connection方法

connection 方法是在tcp的3次握手会被调用,在client-server建立连接成功之后,

function connectionListenerInternal(server, socket) {
  debug('SERVER new http connection');
/**省略代码**/
  parser.onIncoming = parserOnIncoming.bind(undefined, server, socket, state);

  // We are consuming socket, so it won't get any actual data
  socket.on('resume', onSocketResume);
  socket.on('pause', onSocketPause);

  // Override on to unconsume on `data`, `readable` listeners
  socket.on = socketOnWrap;

  // We only consume the socket if it has never been consumed before.
  if (socket._handle) {
    var external = socket._handle._externalStream;
    if (!socket._handle._consumed && external) {
      parser._consumed = true;
      socket._handle._consumed = true;
      parser.consume(external);
    }
  }
  parser[kOnExecute] =
    onParserExecute.bind(undefined, server, socket, parser, state);

  socket._paused = false;
}

tcp建立成功,然后server就需要解析数据,生成一个req与res,同时要emit触发request方法,这样就回到了我们的http.createServer(callback)方法

function parserOnIncoming(server, socket, state, req, keepAlive) {
  resetSocketTimeout(server, socket, state);

  if (req.upgrade) {
    req.upgrade = req.method === 'CONNECT' ||
                  server.listenerCount('upgrade') > 0;
    if (req.upgrade)
      return 2;
  }

  state.incoming.push(req);

  // If the writable end isn't consuming, then stop reading
  // so that we don't become overwhelmed by a flood of
  // pipelined requests that may never be resolved.
  if (!socket._paused) {
    var ws = socket._writableState;
    if (ws.needDrain || state.outgoingData >= socket.writableHighWaterMark) {
      socket._paused = true;
      // We also need to pause the parser, but don't do that until after
      // the call to execute, because we may still be processing the last
      // chunk.
      socket.pause();
    }
  }

  var res = new server[kServerResponse](req);
  res._onPendingData = updateOutgoingData.bind(undefined, socket, state);

  res.shouldKeepAlive = keepAlive;
  DTRACE_HTTP_SERVER_REQUEST(req, socket);
  COUNTER_HTTP_SERVER_REQUEST();

  if (socket._httpMessage) {
    // There are already pending outgoing res, append.
    state.outgoing.push(res);
  } else {
    res.assignSocket(socket);
  }

  // When we're finished writing the response, check if this is the last
  // response, if so destroy the socket.
  res.on('finish',
         resOnFinish.bind(undefined, req, res, socket, state, server));

  if (req.headers.expect !== undefined &&
      (req.httpVersionMajor === 1 && req.httpVersionMinor === 1)) {
    if (continueExpression.test(req.headers.expect)) {
      res._expect_continue = true;

      if (server.listenerCount('checkContinue') > 0) {
        server.emit('checkContinue', req, res);
      } else {
        res.writeContinue();
        server.emit('request', req, res);
      }
    } else if (server.listenerCount('checkExpectation') > 0) {
      server.emit('checkExpectation', req, res);
    } else {
      res.writeHead(417);
      res.end();
    }
  } else {
    server.emit('request', req, res);
  }
  return 0;  // No special treatment.
}
关键代码 server.emit('request', req, res);

这样我们就监听到了客户端的请求。

上一篇 下一篇

猜你喜欢

热点阅读