XingYun blog
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具

XingYun

冲!
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具
  • 有了MAC地址 为什么还需要IP地址
  • 为什么IP地址老是变
  • 我们为什么需要IPV6
  • TCP与IP协议
  • TCP与UDP
  • https与http
  • DNS域名解析
  • 进程与线程
  • SSH
  • 正向代理与反向代理
  • 程序猿必须掌握的英语单词
  • ASCII、Unicode、UTF-8和UTF-16
  • 异或门怎么连
  • 前端够用的linux命令
  • http1.1与http2
  • 与服务器保持连接的几种方式
    • base64编码
    • 关于URL
    • http请求方式
    • 图解http阅读笔记
    • 计算机
    XingYun
    2022-04-15
    目录

    与服务器保持连接的几种方式

    在某些业务场景里,客户端需要和服务端保持即时通信,比如:实时告警, 股票走势, 系统资源占用情况等。

    # ajax 轮询

    最常见最简单的方式就是 ajax 轮询了

    let updateTimer = setInterval(() => {
      getData()
    }, 30000)
    
    1
    2
    3

    这种方法尽量的模拟即时传输,但并非真正意义上的即时通讯,很有可能出现客户端请求时,服务端数据并未更新。或者服务端数据已更新,但客户端未发起请求(30 秒的时间窗口引发的问题)。导致多次请求资源浪费,效率低下。

    # ajax 长轮询

    这种方式还是基于 ajax 请求,不同之处在于客户端发送请求之后,如果没有数据返回,服务端会将请求 挂起(不断开连接)处理其他请求,直到有数据返回给客户端。然后客户端再次发起请求,以此循环。

    这里需要注意两个点:

    • 延长客户端请求超时时间
    • HTTP1.0 需要设置 请求头 Connection:keep-alive 服务端收到该请求头之后知道这是一个长连接,在响应报文头中也添加 Connection:keep-alive

    在 HTTP1.1 或更高版本中默认使用了 Connection:keep-alive 长连接。 注意这里的长连接指的是 TCP(连接层)的长连接,而不是 HTTP(应用层)

    长轮询可以减少客户端的请求,降低无效的网络传输,保证每次请求都有数据返回。

    缺点是无法处理高并发,当客户端请求量大,请求频繁时对服务器的处理能力要求较高。服务器一直保持连接会消耗资源,需要同时维护多个线程(或进程),服务器所能承载的 TCP 连接数是有上限的,这种轮询很容易把连接数打满。

    # WebSocket

    Websocket 协议与 HTTP 协议不同,它是一个建立在 TCP 协议上的全新协议,为了兼容 HTTP 握手规范,在握手阶段依然使用 HTTP 协议,握手完成之后,数据通过 TCP 通道进行传输。

    WebSocket 数据传输是通过 frame(分片) 形式,一个消息可以分成几个片段传输。这样大数据可以分成一些小片段进行传输,不用考虑由于数据量大导致标志位不够的情况。也可以边生成数据边传递消息,提高传输效率。

    示例:

    // 创建WebSocket连接.
    const socket = new WebSocket('ws://localhost:8080')
    
    // 连接成功触发
    socket.addEventListener('open', function(event) {
      socket.send('Hello Server!')
    })
    
    // 监听消息
    socket.addEventListener('message', function(event) {
      console.log('Message from server ', event.data)
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    可以看出 URL 是以 ws: 开头,如果是对应的 HTTPS,则以 wss: 开头。WebSocket 使用 ws 或 wss 为统一资源标志符,其中 wss 表示在 TLS 之上的 Websocket。

    下面是知乎的 wss 连接

    从上面可以看出 WebSocket 和 http 的不同之处

    1. Status Code:101。该状态码表示协议切换。服务器返回了 101 ,表示没有释放 TCP 连接。WebSoket 协议握手阶段还是依赖于 HTTP 协议,到数据传输阶段便切换协议。

    2. 只有 WebSocket 协议才有的字段。请求头:

      • Sec-WebSocket-Extension:表示客户端协商的拓展特性。
      • Sec-WebSocket-Key:是一个 Base64 encode 的密文,由浏览器随机生成,用来验证是否是 WebSocket 协议。
      • Sec-WebSocket-Version:表示 WebSocket 协议版本。
    3. 响应头:

      • Sec-WebSocket-Extension:表示服务端支持的拓展特性。
      • Sec-WebSocket-Accept:与客户端的 Sec-WebSocket-Key 相对应,是经过服务器确认,加密过后的 Sec-WebSocket-Key。

    优点:

    双向通信。客户端和服务端双方都可以主动发起通讯。
    没有同源限制。客户端可以与任意服务端通信,不存在跨域问题(某些大厂的在线客服,一系统对多网站)。
    数据量轻,传输效率高。第一次连接时需要携带请求头,后面数据通信都不需要带请求头,减少了请求头的负荷。

    缺点:

    兼容性,WebSocket 只支持 IE10 及其以上版本。服务器长期维护长连接需要一定的成本,各个浏览器支持程度不一;
    HTTP 生态下有大量的库和组件可用,WebSocket 则没有,遇到异常问题难以快速定位快速解决。
    长连接受网络限制比较大,需要处理好重连。

    #网络
    上次更新: 2023/04/05, 09:41:10
    http1.1与http2
    base64编码

    ← http1.1与http2 base64编码→

    最近更新
    01
    JavaScript-test
    07-20
    02
    二维码的原理
    07-20
    03
    利用ChatGPT优化代码
    07-20
    更多文章>
    Theme by Vdoing | Copyright © 2021-2023 XingYun | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式