HTTP 长连接

HTTP 请求是在TCP连接上进行发送的。而TCP的连接分为:长连接,短连接。

长连接:HTTP 请求发送的时候,要先去创建一个TCP连接,然后在这个TCP连接上,把HTTP 的请求发送并接受完。一次HTTP请求结束了,浏览器就会跟服务端商量是否关闭TCP 连接。如果不关闭,TCP 连接一直开着,会有一定的消耗,但如果还有请求,可以直接在这个TCP 上发送(不需要经过三次握手这样的连接的消耗);如果关闭了,下次有请求的时候,就会重新创建连接,但它的好处是请求完即关闭能减少服务端与客户端并发连接数。

实际情况,网址的并发量可能比较大,当创建连接的次数很多时,它实际的开销可能比维持一个长连接的开销还要高一些。而且,长连接可以设置timeout (过多长时间在这个TCP 上没有请求,就会关闭),并不会一直保持这连接。因此,一般我们实际使用中,使用的都是长连接

我们随意打开一个网站,打开控制台。点开network,然后看ConnectionID (同一个ID即同一个TCP连接),就能看到很多重复的ID。也就是存在长连接。

在HTTP1.1 版本中,HTTP连接在TCP连接中是有先后顺序的。意思是,比如有十个请求,不能并发的在一个TCP连接上发送。在一个TCP连接上,只能一个接一个发送。当我们在加载首页的时候,当然是希望它可以并发发送HTTP请求,这个时候,浏览器是可以允许创建并发的TCP连接,比如Chrome 允许的是6个(并发TCP连接)。正常情况下,我们在Chrome 中,加载首页,可以达到并发创建6个TCP连接。当页面后面还要有并发的TCP连接,那么该TCP连接将等待,浏览器会等前面的六个TCP连接中有结束的了,再调用新的TCP连接。

那么,如何保证我们的服务创建的是长连接,而不是短连接呢。我们看HTTP 请求和返回的Request Headers,Response Headers 中的Connection,如下。值是“keep-alive” 时,则表示这个连接是长连接。(发送请求的时候,浏览器希望是长连接的;如果返回的Connection 也是keep-alive 那么这个连接就是长连接的)。Connection 一般使用两个值:“keep-alive”/"close"

下面我们来实验一下。

新建一个目录,放入三个文件:server.js, test.html, dance.jpg。

下面是server.js 代码 (它的做法是,url 为根时,返回html 页面;url 为其他时,返回dance.jpg)

const http = require('http')
const fs = require('fs')

http.createServer(function(request, response) {
    console.log('request come', request.url)

    const html = fs.readFileSync('./test.html', 'utf-8')
    const image = fs.readFileSync('./dance.jpg')

    if (request.url === '/') {
        response.writeHead(200, {
            'Content-Type': 'text/html',
        })
        response.end(html)
    } else {
        response.writeHead(200, {
            'Content-Type': 'image/jpg',
        })
        response.end(image)
    }
}).listen(8888)

console.log('serve listening on 8888')

下面是 test.html (它的里面有7个不同的 url,这样就会发送7次HTTP 请求 )

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>MyHtml</title>
    <style>
        img {
            display: block;
            width: 100px;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div>hello world</div>
    <div>don't speak</div>

    <img src="/test1.jpg" alt="dance"/>
    <img src="/test2.jpg" alt="dance"/>
    <img src="/test3.jpg" alt="dance"/>
    <img src="/test4.jpg" alt="dance"/>
    <img src="/test5.jpg" alt="dance"/>
    <img src="/test6.jpg" alt="dance"/>
    <img src="/test7.jpg" alt="dance"/>

</body>
</html>

我们在浏览器里,把网络调慢一点,如下。

然后我们刷新网页,就可以看到下面这样。test7.jpg 的请求,由于TCP 连接数用尽,因此等待了会儿。

下面我们将Conneciton 设为“close”,如下。

const http = require('http')
const fs = require('fs')

http.createServer(function(request, response) {
    console.log('request come', request.url)

    const html = fs.readFileSync('./test.html', 'utf-8')
    const image = fs.readFileSync('./dance.jpg')

    if (request.url === '/') {
        response.writeHead(200, {
            'Content-Type': 'text/html',
            'Connection': 'close'
        })
        response.end(html)
    } else {
        response.writeHead(200, {
            'Content-Type': 'image/jpg',
            'Connection': 'close'
        })
        response.end(image)
    }
}).listen(8888)

console.log('serve listening on 8888')

我们刷新页面,如下,ConnectionID 没有复用的。

最后,在HTTP2.0 中,由于使用了信道复用技术,可以在同一个TCP连接中并发地发送HTTP 请求,也就是说请求一个网站的数据的时候,只需要一个TCP连接。

  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值