资讯专栏INFORMATION COLUMN

【Node核心模块HTTP】

figofuture / 1940人阅读

摘要:比如,大块编码的消息。这些接口不缓冲完整的请求或响应,用户能够以流的形式处理数据。它只涉及流处理与消息解析。结构图由于该模块中的内容比较多,图片我就分开传了,避免一张图密密麻麻的。请求遇到问题写入数据到请求主体

环境:Node v8.2.1; Npm v5.3.0; OS Windows10
客户端、服务端对我们都不陌生,Node.js 中的 HTTP 接口被设计成支持协议的许多特性。 比如,大块编码的消息。 这些接口不缓冲完整的请求或响应,用户能够以流的形式处理数据。

为了支持各种可能的 HTTP 应用,Node.js 的 HTTP API 是非常底层的。 它只涉及流处理与消息解析。 它把一个消息解析成消息头和消息主体,但不解析具体的消息头或消息主体。

1、API结构图

由于该模块中的内容比较多,图片我就分开传了,避免一张图密密麻麻的。

1.1 模块类结构图

1.2 Agent类结构图

1.3 ClientRequest类结构图

1.4 Server 类结构

1.5 ServerResponse类结构图

1.6 IncomingMessage类结构图

1.7 静态方法和属性图

2、类关系

在看API之前,我还是简单的缕一缕上面几个类的关系吧,从一个简单的例子开始

2.1 简单且核心的例子
const http = require("http");
//server
const server = http.createServer((clientReq,serverRes)=>{
    serverRes.end();
}).listen(3000)

//client
const client=http.get("http://localhost:3000",(clientRes)=>{
    
})

上面那么简单的几行代码已经成功创建了一个server和一个client,看似简单,实际上却不这样,上面代码以一共创建了4个实例,可以对照着顶部的那张图看。

server:http.Server 类的实例,用来提供服务,处理客户端的请求。

client:http.ClientRequest 类的实例,用于向服务端发起请求

clientReq/clientRes:http.IncomingMessage 类的实例,【clientReq】用于服务端获取客户端请求的信息,【clientRes】用于客户端获取服务端返回的相关消息

serverRes:http.ServerResponse 类实例,用于服务端响应客户端请求

2.2 类关系图

图片有点乱,在画图本里面拖出来的,讲究看吧,下面贴出继承关系的源码,只贴框架,里面具体的内容就不贴了,贴出来感觉蛮乱的。

http.IncomingMessage 类继承 stream.Readable:

  export class IncomingMessage extends stream.Readable {}

http.ServerResponse 类继承stream.Writable:

export class OutgoingMessage extends stream.Writable {}

export class ServerResponse extends OutgoingMessage {}
3、一些例子

下面是部分API的例子,对部分API的一个简单代码实现

3.1 server属性
const http = require("http");
const server=http.createServer((ClientRequest,ServerResponse)=>{
  ServerResponse.end();
})
server.listen(3000);
console.log("listening: "+server.listening);
console.log("maxHeadersCount: "+server.maxHeadersCount);
console.log("timeout: "+server.timeout);
console.log("keepAliveTimeout: "+server.keepAliveTimeout);


// listening: true
// maxHeadersCount: null (没有限制)
// timeout: 120000
// keepAliveTimeout: 5000
3.2 server事件
const http = require("http");

const server = http.createServer((ClientRequest, ServerResponse) => {
    ServerResponse.end();
}).listen(3000);

server.on("request", (request, response) => {
    console.log("服务端收到请求");
})

server.on("connection",socket=>{
    //超过默认的5000msTCP流会被关闭,再次请求时会被重新建立
    console.log("一个新的 TCP 流被建立");
})
3.3 serverResponse属性
const http = require("http");
const server = http.createServer((ClientRequest, ServerResponse) => {
    ServerResponse.writeHead(200, { "Content-Type": "text/plain"});
    ServerResponse.write("hello world");
    console.log("connection: "+ServerResponse.connection);
    console.log("finished: "+ServerResponse.finished);
    console.log("headersSent: "+ServerResponse.headersSent);
    console.log("sendDate: "+ServerResponse.sendDate);
    console.log("socket: "+ServerResponse.socket);
    console.log("statusCode: "+ServerResponse.statusCode);
    console.log("statusMessage: "+ServerResponse.statusMessage);
    ServerResponse.end();
    console.log("finished: "+ServerResponse.finished);
}).listen(3000);
/*
    connection: [object Object]
    finished: false
    headersSent: true
    sendDate: true
    socket: [object Object]
    statusCode: 200
    statusMessage: OK
    finished: true
*/
3.4 addTrailers()
const http = require("http");
const server = http.createServer((ClientRequest, ServerResponse) => {
    ServerResponse.writeHead(200, { "Content-Type": "text/plain" });
    ServerResponse.write("hello world");
    ServerResponse.addTrailers({"Content-MD5": "7895bf4b8828b55ceaf47747b4bca667"})
    ServerResponse.end();
}).listen(3000);
3.5 getHeader()
const http = require("http");
const server = http.createServer((ClientRequest, ServerResponse) => {
    ServerResponse.setHeader("foo","bar");
    ServerResponse.writeHead(200, { "Content-Type": "text/plain" });
    ServerResponse.write("hello world");
    console.log(ServerResponse.getHeader("foo"));
    ServerResponse.end();
}).listen(3000);
3.6 getHeaderNames()
const http = require("http");
const server = http.createServer((ClientRequest, ServerResponse) => {
    ServerResponse.setHeader("foo","bar");
    ServerResponse.writeHead(200, { "Content-Type": "text/plain" });
    ServerResponse.write("hello world");
    console.log(ServerResponse.getHeaderNames());
    //[ "foo", "content-type" ]
    ServerResponse.end();
}).listen(3000);
3.7 get()
const http = require("http");
const ClientRequest = http.get("http://localhost:3000", res => {
    res.setEncoding("utf8")
    let rawData = "";
    res.on("data", chunk => {
        rawData += chunk;
    })
    res.on("end", () => {
        console.log(rawData);
    })
})
ClientRequest.on("response", (imsg) => {
    console.log("收到响应");
})
3.8 http.request

摘一个官方例子^_^

const postData = querystring.stringify({
  "msg" : "Hello World!"
});

const options = {
  hostname: "www.google.com",
  port: 80,
  path: "/upload",
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
    "Content-Length": Buffer.byteLength(postData)
  }
};

const req = http.request(options, (res) => {
  console.log(`状态码: ${res.statusCode}`);
  console.log(`响应头: ${JSON.stringify(res.headers)}`);
  res.setEncoding("utf8");
  res.on("data", (chunk) => {
    console.log(`响应主体: ${chunk}`);
  });
  res.on("end", () => {
    console.log("响应中已无数据。");
  });
});

req.on("error", (e) => {
  console.error(`请求遇到问题: ${e.message}`);
});

// 写入数据到请求主体
req.write(postData);
req.end();

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88796.html

相关文章

  • Node】前后端模块规范与模块加载原理

    摘要:例如指定一些依赖到模块中实现规范的模块化,感兴趣的可以查看的文档。 CommonJS 定义了 module、exports 和 require 模块规范,Node.js 为了实现这个简单的标准,从底层 C/C++ 内建模块到 JavaScript 核心模块,从路径分析、文件定位到编译执行,经历了一系列复杂的过程。简单的了解 Node 模块的原理,有利于我们重新认识基于 Node 搭建的...

    jsyzchen 评论0 收藏0
  • node核心特性理解

    摘要:概述本文主要介绍了我对的一些核心特性的理解,包括架构特点机制核心模块与简单应用。在此期间,主线程继续执行其他任务。延续了浏览器端单线程,只用一个主线程执行,不断循环遍历事件队列,执行事件。 原文地址在我的博客,转载请注明来源,谢谢! node是在前端领域经常看到的词。node对于前端的重要性已经不言而喻,掌握node也是作为合格的前端工程师一项基本功了。知道node、知道后端的一些东西...

    huangjinnan 评论0 收藏0
  • 深入浅出Node.js

    摘要:深入浅出一直想致力于写一篇关于广义讲解系统的文章,苦于时间有限,资源有限。事件驱动机制是通过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文的切换。 深入浅出Node.js 一直想致力于写一篇关于广义讲解Node.js系统的文章,苦于时间有限,资源有限。这篇文章是在结合自己的学习心得以及与行业大佬共同探讨下争对于熟练掌握JS语言后的广义Node.js.至于为什么...

    oujie 评论0 收藏0
  • 深入浅出Node.js

    摘要:深入浅出一直想致力于写一篇关于广义讲解系统的文章,苦于时间有限,资源有限。事件驱动机制是通过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文的切换。 深入浅出Node.js 一直想致力于写一篇关于广义讲解Node.js系统的文章,苦于时间有限,资源有限。这篇文章是在结合自己的学习心得以及与行业大佬共同探讨下争对于熟练掌握JS语言后的广义Node.js.至于为什么...

    MadPecker 评论0 收藏0
  • 深入浅出Node.js

    摘要:深入浅出一直想致力于写一篇关于广义讲解系统的文章,苦于时间有限,资源有限。事件驱动机制是通过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文的切换。 深入浅出Node.js 一直想致力于写一篇关于广义讲解Node.js系统的文章,苦于时间有限,资源有限。这篇文章是在结合自己的学习心得以及与行业大佬共同探讨下争对于熟练掌握JS语言后的广义Node.js.至于为什么...

    lily_wang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<