当前位置:首页 > 科技  > 软件

别背八股文了,WebSocket 是什么,我劝你花几分钟让面试官惊艳!

来源: 责编: 时间:2024-06-05 17:39:25 78观看
导读前言作为前端工程师,我们几乎每天都在使用 ajax / fetch 请求与后端进行数据交互,这种基于请求-响应的通讯模式,我们再熟练不过了,无论是C端产品或者是B端产品,都离不开这种通讯模式。但是像即时通讯IM类场景,通常不会选择

前言

作为前端工程师,我们几乎每天都在使用 ajax / fetch 请求与后端进行数据交互,这种基于请求-响应的通讯模式,我们再熟练不过了,无论是C端产品或者是B端产品,都离不开这种通讯模式。但是像即时通讯IM类场景,通常不会选择这种“你来我回”的通信模式,而是会选择 WebSocket 这类的全双工通信模式。9X528资讯网——每日最新资讯28at.com

本文会带您全方位去了解一下 WebSocket 的本质,方便您搞清楚“Connection: Upgrade 是什么意思,为什么是它?”、“Upgrade: WebSocket 又是什么意思?这就可以双向通信了?”、“WebSocket 和 HTTP/TCP 到底有什么关联?八股文背了还是不理解”之类的问题,帮助您无论面试或工作时被问到 WebSocket 都能有更多细节可以聊,妥妥的一个加分项!9X528资讯网——每日最新资讯28at.com

最后通过一个在线聊天室实战案例带大家熟悉下 WebSocket 的全栈使用,可点击在线聊天室[3]进行体验。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

认识 WebSocket

WebSocket 是一种网络通信协议,它建立在 HTTP 之上,提供了在单个 TCP 连接上进行全双工通信的能力。这意味着服务器和客户端可以互相发送和接收消息,而不需要每次都重新建立连接。WebSocket 最初由 HTML5 规范定义,具体可以参考WebSockets Living Standard[4]。而现在,WebSocket 已被广泛支持并应用于各种应用,包括实时聊天、多人在线游戏、股票交易系统等需要实时数据更新的场景。9X528资讯网——每日最新资讯28at.com

WebSocket 的兼容性如何?

作为前端开发,对 API 的兼容性还是非常敏感的,我们先来看看 WebSocket 的兼容性怎么样。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

可以看到,主流浏览器都支持了 WebSocket,IE10 及以上版本也对 WebSocket 提供了完备的支持,所以我们可以大胆地使用起来!9X528资讯网——每日最新资讯28at.com

WebSocket 的前端用法

浏览器 JS 运行时提供了 WebSocket[5] 这个 API,可以用来创建和管理 WebSocket 连接。9X528资讯网——每日最新资讯28at.com

使用也非常简单,构造实例后只有几个简单的方法调用,一看就会。9X528资讯网——每日最新资讯28at.com

// 创建一个新的 WebSocket 连接const socket = new WebSocket('ws://your-websocket-server-url')// 监听连接打开socket.onopen = (e) => {  console.log('WebSocket is connected.')  // 连接打开后,你可以发送消息  socket.send('Hello Server!')}// 监听消息socket.onmessage = (e) => { console.log('Message from server: ', e.data) }// 监听关闭socket.onclose = (e) => { console.log('Connection closed.') }// 监听错误socket.onerror = (err) => { console.error('WebSocket Error: ', err) }// 如果你想主动关闭连接,可以调用 close 方法// socket.close()

wss:// 是 ws:// 的 TLS 加持版,可以类比于 https:// 和 http://9X528资讯网——每日最新资讯28at.com

Nodejs 原生支持 WebSocket 吗?

WebSocket 前端的使用非常简单,我自然会联想到:如果我做全栈开发,用 Nodejs 实现 WebSocket 服务端,有原生的模块可以支持吗?9X528资讯网——每日最新资讯28at.com

经过查询了解到,Node 原生模块中并未直接支持 WebSocket 服务端的开箱使用,一个比较流行的库是 ws[6]。9X528资讯网——每日最新资讯28at.com

那么 ws 这个库是怎么实现 WebSocket 服务端的呢?怎么才能和浏览器的 WebSocket 实现对接上?9X528资讯网——每日最新资讯28at.com

直接读源码肯定是看不懂的,即便看懂了一些过程调用,也是懵逼的,我们往下看。9X528资讯网——每日最新资讯28at.com

WebSocket 协议概览

我们知道,通讯是基于协议的,WebSocket 也有它的专属协议。ws 的实现它也是要遵循这个协议,才能和客户端实现匹配上,完成通讯。9X528资讯网——每日最新资讯28at.com

这个协议我们去哪里看呢?根据 wikipedia 的介绍,我们知道,WebSocket 的标准化是基于IETF 的 RFC 6455 WebSocket Protocol[7]。大致浏览后,我圈出了协议里一些值得关注的内容。阅读这类协议时,我们可以先挑重点看,对协议有一个基本的认识即可。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

我们了解到一些关键词:9X528资讯网——每日最新资讯28at.com

  1. 连接握手
  2. 怎么建立连接
  3. 数据发送和接收,数据帧
  4. 关闭握手
  5. 插件,相关 HTTP 头部字段

虽然有了一些关键词在脑海中,但我们对整个通讯过程肯定还有一连串疑问。带着疑问,我们继续往下看协议的具体内容。9X528资讯网——每日最新资讯28at.com

  1. 我们会了解到 WebSocket 出现的背景,它是为了解决什么,很显然,普通的 HTTP 请求不适合一些双向通信场景,比如聊天、股票、游戏等。
  2. 即便普通 HTTP 请求能通过一些业务设计满足双向通信需求,性能问题也很大,TCP 连接的开销等问题都要考虑在内。
  3. WebSocket 就是希望在一个 TCP 连接上,开辟双工通道,实现全双工实时通信。
  4. 之所以选择在 HTTP 协议的基础上去实现 WebSocket,也是一种权衡和取舍,可能会牺牲一些性能,但是也极大地复用了已有的网络基础设施,包括协议、安全、代理、认证等。

图片图片9X528资讯网——每日最新资讯28at.com

WebSocket 协议 - 连接握手

再往下翻一翻协议,我们能翻到最关键的部分,这也是面试里能和面试官吹的内容,请仔细看!9X528资讯网——每日最新资讯28at.com

很多人面试被问到 WebSocket,就说 WebSocket 可以双向通信,这是和 HTTP 最大的不同。讲道理,这种回复面试官已经听腻了。9X528资讯网——每日最新资讯28at.com

如果你能告诉面试官,WebSocket 的协议涉及到以下几个 HTTP 头部字段,并简述一下各个字段的简单含义,我相信你的面试绝对加分!9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

我们先看请求头:9X528资讯网——每日最新资讯28at.com

  • WebSocket 请求一定是 GET 类型的。
  • Origin: 浏览器客户端会带上,包含 Origin 是为了安全考虑,充分利用浏览器的同源策略。
  • Connection: Upgrade 和 Upgrade: websocket。这是客户端告知服务端需要升级协议,并且升级的协议为 websocket。
  • Sec-WebSocket-Key:由客户端(比如浏览器)随机生成,16位随机数经过 base64 编码后得到。响应头 Sec-WebSocket-Accept 是与它搭配使用的,用来确保请求的有效性和安全性。
  • Sec-WebSocket-Protocol:不是必选的。用来约定应用层面的子协议,使得客户端和服务器能够灵活地协商并选择一个双方都能理解的协议来进行通信。如果服务端选择使用某个子协议通信,则会在响应头中返回。

再看响应头:9X528资讯网——每日最新资讯28at.com

  • 服务端返回 101 Switching Protocols,代表握手成功,协议切换到 WebSocket。
  • Connection: Upgrade 和 Upgrade: websocket,用于告知客户端可以升级为 websocket 协议。
  • Sec-WebSocket-Accept:基于 Sec-WebSocket-Key 处理得到,处理公式如下,其中"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"是一个固定的字符串:
base64-encode(sha1(Sec-WebSocket-Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))

引用 wikipedia 的一张图,可以看得更清楚!9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

WebSocket 协议 - 数据帧

建立了连接握手后,WebSocket 就可以发送和接受消息数据了,消息是由一个或多个帧组成的。我们先看看这两张图了解一下数据帧的结构。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

其中 Opcode 是操作码,具体见下表。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

由于存在数据比较大的可能,这时需要切片传输,WebSocket 消息数据支持分片传输。9X528资讯网——每日最新资讯28at.com

  • 当 FIN = 1 且 OpCode ≠ 0 时,代表这一帧数据不是分片处理的。
  • 当 FIN = 0 时,如果 OpCode = 0,代表这一帧数据是某个分片的中间数据帧;如果 OpCode ≠ 0,代表这一帧数据是一个分片数据中的起始帧。

WebSocket 能发送文本数据或二进制数据,这个是体现在 OpCode 上。如果起始帧的 OpCode 是 1,则代表是文本数据;如果起始帧的 OpCode 是 2,则代表是二进制数据。9X528资讯网——每日最新资讯28at.com

WebSocket 协议 - 关闭连接

我们看看规范中,关闭握手这部分是怎么说的。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

WebSocket 任何一端都可以发起关闭连接。9X528资讯网——每日最新资讯28at.com

当一方准备关闭连接时,应该发送 Close Frame 开始关闭握手,之后不应该再发送任何数据;9X528资讯网——每日最新资讯28at.com

另一方收到 Close Frame 时,需要回复 Close Frame,并且准备释放资源,同时也应该丢弃后续从这个连接上可能接收到的数据。9X528资讯网——每日最新资讯28at.com

发起方收到 Close Frame 控制帧后,关闭连接释放资源,不再接收数据。9X528资讯网——每日最新资讯28at.com

这种 WebSocket 关闭握手机制也是在 TCP 握手机制上的一种补充,更好地保证端到端通信的可靠性!9X528资讯网——每日最新资讯28at.com

有的朋友可能会考虑到这个问题:当客户端发送 Close Frame 后,服务端正常接收到,并且回复 Close Frame,但是由于网络问题客户端没有服务端响应的 Close Frame,这种情况是怎么关闭 WebSocket 连接的?9X528资讯网——每日最新资讯28at.com

实际上,TCP 连接也有它的超时和重试机制,当一段时间内没有数据传输时,也会断开连接。所以我们无需担心这一点。9X528资讯网——每日最新资讯28at.com

当这种没有成功关闭握手但是关闭了 TCP 连接的情况发生时,onclose事件回调中收到的错误码应该是 1006,这一点可以在上面的表格中找到。9X528资讯网——每日最新资讯28at.com

正常关闭是 1000。9X528资讯网——每日最新资讯28at.com

在实际业务实现上,还会通过 ping-pong 之类的心跳检测机制来保证可靠性。9X528资讯网——每日最新资讯28at.com

回顾 ws 关键源码

有了这些知识储备后,再来看 ws 的实现源码,可能就会有头绪一点。9X528资讯网——每日最新资讯28at.com

当你看到这部分,你会知道它在校验头部字段是否符合协议要求,准备升级协议...9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

当你看到这个 101 状态码,你会恍然大悟:“哦,原来是在这里完成了协议的升级!”虽然还有些细节看不懂,但是无伤大雅!9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

当你看到这里时,你会知道,如果客户端尝试通过普通的 HTTP 请求来连接 WebSocket 服务,服务端应该返回 426 Upgrade Required 告诉客户端,“你该升级协议再跟我对话!”9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

本文不是源码解读,点到为止,我们往下看。9X528资讯网——每日最新资讯28at.com

为什么选择 Socket.IO

实际将 WebSocket 运用到生产环境时,我们一般不会直接使用 ws 这种协议实现库,而是会选择在应用层面进行了一些封装的库,比如 Socket.IO[8]。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

这是因为在 WebSocket 实际使用过程中,还有很多问题要考虑,比如心跳检测、优雅降级、房间隔离、命名空间隔离、API 的易用性等。而这些,Socket.IO 已经开箱支持。9X528资讯网——每日最新资讯28at.com

准确说,Socket.IO 并非是一个 WebSocket 实现,而是一个事件驱动的低延迟双向通讯方案。9X528资讯网——每日最新资讯28at.com

它的底层通讯不一定是基于 WebSocket 的,可能会根据情况选择 HTTP 长轮询、WebTransport[9]。9X528资讯网——每日最新资讯28at.com

WebTransport 是一个基于 HTTP/3 的通讯技术,可实现可靠通信和不可靠通信。HTTP/3 底层基于 Google 的 QUIC 协议,而 QUIC 协议是基于 UDP 的。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

Socket.IO 有它的约定和规则,或者叫协议,只要遵循这个协议,就能完成客户端和服务端的实现,所以你会看到,它也有多语言的实现,甚至在客户端还有小程序的实现。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

这个协议其实也就对应着Socket.IO 的底层引擎 Engine.IO[10]。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

虽然现在大部分浏览器都支持了 WebSocket,但是也不排除某些远古项目的存在,它必须运行在“古董”浏览器版本之上。Socket.IO 考虑到了这一点,它的自动优雅降级完美解决了这一问题。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

Socket.IO 的心跳检测机制和自动重连也是实际业务中必不可少的!9X528资讯网——每日最新资讯28at.com

更多的特性还有:9X528资讯网——每日最新资讯28at.com

  • 对话回调
  • 广播
  • 房间
  • 命名空间多路复用
  • ...

Socket.IO 的通讯过程

当我们打开一个 Socket.IO 的客户端页面时,会发现 Network 里发出了多个请求,在 101 websocket 连接建立之前,有 4 个 xhr 请求,其中还有一个是 POST 请求。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

Socket.IO 在升级机制中解释了这一点,直接建立可靠可用的 WebSocket 连接并非一件很轻松的事情,通常从 HTTP 开始平滑升级到 WebSocket,对连接的可靠性和用户体验来说是更好的。9X528资讯网——每日最新资讯28at.com

升级协议会经历这么一些步骤,对应着我们在上面看到的几个 Network 请求。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

我这个项目开始得很早,所以EIO=3,代表协议版本号是3,目前 Engine.IO 已经升级到版本4了。9X528资讯网——每日最新资讯28at.com

在 Socket.IO 的 HTTP 长轮询模式中,使用长时间运行的 GET 请求接收数据,使用短期运行的 POST 请求发送数据。9X528资讯网——每日最新资讯28at.com

了解了这些机制,并且查看 API 用法后,就可以开始运用了,一些高级用法可以在使用过程中再去探索!9X528资讯网——每日最新资讯28at.com

聊天室的全栈实现

基于以上理解,我们开始搭建博客项目中的聊天室功能,我们会实现这些主要能力:9X528资讯网——每日最新资讯28at.com

  • 成功创建 Socket.IO 连接
  • 展示聊天室的系统通知信息(涉及到单播和广播)
  • 聊天对话功能(广播)

我们首先把依赖安装好,客户端使用socket.io-client[11],服务端使用socket.io[12]即可。9X528资讯网——每日最新资讯28at.com

服务端开启 WebSocket 服务

第一步是把 WebSocket 服务启动。由于本项目开始较早,socket.io 版本是 2.5,大家对照文档的时候按 2.x 文档看就好。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

socket.io 可以利用已经存在的 HTTP 服务,由于项目是用 Express 搭建的,我们直接与 Express 共享一个 HTTP 服务即可。9X528资讯网——每日最新资讯28at.com

io 实例化后,监听到 connection 事件就代表有客户端过来了,可以开始干活了。我这里是把聊天室相关的逻辑都放在了 chatroom 这个命名空间下。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

of 的作用就是初始化并使用命名空间。9X528资讯网——每日最新资讯28at.com

客户端服务端建立连接

第二步是建立连接。首先引入依赖。9X528资讯网——每日最新资讯28at.com

import io from "socket.io-client";

再进行实例化,得到一个 socket 实例。9X528资讯网——每日最新资讯28at.com

this.socket = io(process.env.VUE_APP_SOCKET_SERVER + "/chatroom");

有了这个 socket,我们就能监听各种事件了。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

聊天室的系统通知信息

当一个客户端连接上服务器时,服务器会发送一条消息,“hello,欢迎您加入在线聊天室!”这是通过单播实现的,只要拿着socket对象,调用其emit方法就行。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

除了对这个客户端打招呼外,还需要告诉其他用户,有新人加入了。这是通过socket.broadcast广播实现的。9X528资讯网——每日最新资讯28at.com

socket.broadcast.emit('broadcast', param);

当有人退出聊天室,会触发 disconnect 事件,此时我们可以广播通知其他人。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

这就是我们在前端页面看到的效果:9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

聊天对话功能

由于我们做的是聊天室,相当于一个群聊,就不涉及到单播聊天了,直接用广播就行。9X528资讯网——每日最新资讯28at.com

用户在客户端发聊天消息时,是用到socket对象的emit进行发送。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

这个chat事件是在客户端连接上服务端时开始监听的,在这个回调里,我们需要把内容广播给除发送者之外的其他用户,子事件名是new_chat_content。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

而其他用户则会通过客户端监听广播事件中的new_chat_content子事件拿到聊天数据,最终呈现到界面上。9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

图片图片9X528资讯网——每日最新资讯28at.com

以上都是通讯上的设计,了解了这个机制,UI 的展示就非常简单了,毕竟 UI = Render(data),不做更多介绍!9X528资讯网——每日最新资讯28at.com

小结

本文中,我首先分享了我对 WebSocket 协议的一些理解,希望对还不太理解这块的朋友起到一点帮助作用。面试里,WebSocket 是一个常问的考点,如果你回答的仅仅是“全双工通信”,可能并不能起到一个很好的效果,把文中小知识甩面试官脸上吧,哈哈哈!9X528资讯网——每日最新资讯28at.com

最终通过一个实际案例,带大家理解一个聊天室功能的设计思路,在实际落地的过程中夯实对 WebSocket 协议的理解。9X528资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-92103-0.html别背八股文了,WebSocket 是什么,我劝你花几分钟让面试官惊艳!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: sync.WaitGroup和sync.Once的爱恨情仇

下一篇: Python 中 20 个鲜为人知的字符串函数

标签:
  • 热门焦点
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • K8S | Service服务发现

    K8S | Service服务发现

    一、背景在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;图片对于测试「Tes」环境或者
  • 十个简单但很有用的Python装饰器

    十个简单但很有用的Python装饰器

    装饰器(Decorators)是Python中一种强大而灵活的功能,用于修改或增强函数或类的行为。装饰器本质上是一个函数,它接受另一个函数或类作为参数,并返回一个新的函数或类。它们通常用
  • 三万字盘点 Spring 九大核心基础功能

    三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 华为Mate 60系列用上可变灵动岛:正式版体验将会更出色

    华为Mate 60系列用上可变灵动岛:正式版体验将会更出色

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • 郭明錤称华为和江淮汽车合作开发问界MPV,定价100万左右、计划明年量产

    郭明錤称华为和江淮汽车合作开发问界MPV,定价100万左右、计划明年量产

    8 月 1 日消息,郭明錤今天在 Medium 平台发布博文,称华为正在和江淮汽车合作,开发售价在 100 万元的问界 MPV,预计在 2024 年第 2 季度量产,销量目标为
  • 2纳米决战2025

    2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • iQOO Neo8 Pro评测:旗舰双芯加持 最强性能游戏旗舰

    iQOO Neo8 Pro评测:旗舰双芯加持 最强性能游戏旗舰

    【Techweb评测】去年10月,iQOO推出了一款Neo7手机,该机搭载了联发科天玑9000+,配备独显芯片Pro+,带来了同价位段最佳的游戏体验,一经上市便受到了诸多用
  • Counterpoint :OPPO双旗舰战略全面落地 高端产品销量增长22%

    Counterpoint :OPPO双旗舰战略全面落地 高端产品销量增长22%

    2023年6月30日,全球行业分析机构Counterpoint Research发布的《中国智能手机高端市场白皮书》显示,中国智能手机品牌正在寻求高质量发展,中国高端智能
Top