一、为什么需要 WebSocket
普通 HTTP 有一个问题:
客户端发请求
↓
服务器返回响应
↓
连接结束
服务器不能主动给客户端发消息。
例如:
微信聊天
在线客服
股票行情
在线游戏
聊天室
这些场景需要:
服务器主动推送消息
于是出现了:
WebSocket
二、WebSocket 是什么
一句话理解:
WebSocket = HTTP握手 + TCP长连接 + 全双工通信
普通 HTTP:
客户端说一句
服务器回一句
WebSocket:
客户端和服务器一直保持连接
双方随时都能发消息
类似打电话:
HTTP = 发短信
WebSocket = 打电话
三、WebSocket 建立连接全过程
第一步:建立 TCP 连接
前端:
const ws = new WebSocket("ws://localhost:8000/ws")
浏览器不会立刻发送 WebSocket 数据。
而是先进行:
TCP三次握手
客户端
↓ SYN
服务器
↓ SYN+ACK
客户端
↓ ACK
连接建立成功。
第二步:发送 HTTP Upgrade 请求
浏览器发送:
GET /ws HTTP/1.1
Host: localhost:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xxxxx
重点:
Upgrade: websocket
意思:
我要把HTTP升级成WebSocket
第三步:服务器同意升级
Gin:
conn, err := upgrader.Upgrade(w, r, nil)
返回:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
状态码:
101 Switching Protocols
意思:
同意升级协议
第四步:进入 WebSocket 模式
升级完成后:
这条TCP连接不再传输HTTP
开始传输WebSocket帧
变成:
客户端 ←→ 服务器
双方随时发送消息。
四、聊天室项目中的 WebSocket
一般会有两个协程。
Read 协程
负责接收客户端消息。
go client.Read()
内部:
for {
_, msg, err := c.Conn.ReadMessage()
}
流程:
浏览器
↓
TCP连接
↓
Read协程
↓
ChatServer
Write 协程
负责给客户端推送消息。
go client.Write()
内部:
for {
msg := <-c.Send
c.Conn.WriteMessage(…)
}
流程:
ChatServer
↓
Send Channel
↓
Write协程
↓
TCP连接
↓
浏览器
整体架构
浏览器A
↓
Read协程
↓
ChatServer
↓
Send Channel
↓
Write协程
↓
浏览器B
五、为什么 WebSocket 能全双工
HTTP:
客户端发
服务器回
不能同时发送。
WebSocket:
客户端发
服务器也能发
双方独立工作。
客户端 ←→ 服务器
因此叫:
全双工通信
六、HTTP 与 WebSocket 对比
| 连接方式 | 请求响应 | 长连接 |
| 是否实时 | 否 | 是 |
| 是否双向 | 否 | 是 |
| 是否保持连接 | 否 | 是 |
| 应用场景 | 网页接口 | 聊天室、游戏 |
七、HTTPS 是什么
HTTP 最大的问题:
明文传输
例如:
账号:admin
密码:123456
网络中的任何人都能看到。
于是出现:
HTTPS
HTTPS 本质
HTTPS = HTTP + SSL/TLS
也就是:
HTTP协议
+
加密层
八、证书是什么
证书类似:
身份证
服务器要证明:
我是我自己
例如:
www.baidu.com
必须证明自己真的是百度。
证书由:
CA(证书机构)
签发。
例如:
Let's Encrypt
DigiCert
GlobalSign
九、HTTPS 建立过程
第一步
客户端请求:
我要建立HTTPS连接
第二步
服务器发送证书。
服务器
↓
SSL证书
第三步
浏览器验证证书。
验证:
是不是正规CA签发
有没有过期
域名是否匹配
第四步
生成随机密钥。
Session Key
第五步
后续通信全部加密。
客户端
↓ 加密
互联网
↓ 解密
服务器
即使被截获:
也看不懂内容
十、HTTP 与 HTTPS 对比
| 是否加密 | 否 | 是 |
| 是否安全 | 否 | 是 |
| 默认端口 | 80 | 443 |
| 是否需要证书 | 否 | 是 |
十一、Gin 中的 HTTPS
HTTP:
r.Run(":8000")
HTTPS:
r.RunTLS(
":443",
"server.crt",
"server.key",
)
需要:
证书文件
私钥文件
十二、从输入 URL 到页面显示全过程
假设输入:
http://localhost:8080
第一步:解析域名
浏览器首先获取 IP。
localhost
特殊情况:
localhost = 127.0.0.1
操作系统直接返回。
不经过 DNS。
如果是:
www.baidu.com
则需要:
DNS解析
获取真实 IP。
第二步:TCP 三次握手
浏览器:
SYN
服务器:
SYN + ACK
浏览器:
ACK
建立 TCP 连接。
第三步:发送 HTTP 请求
GET / HTTP/1.1
Host: localhost:8080
发送给 Gin。
第四步:Gin 路由匹配
例如:
r.GET("/", Index)
执行:
Index()
第五步:返回 HTML
返回:
<html>
<head>
</head>
<body>
</body>
</html>
浏览器开始解析。
第六步:发现静态资源
HTML:
<link href="style.css">
<script src="app.js"></script>
<img src="logo.png">
浏览器发现:
CSS
JS
图片
继续发请求。
第七步:获取资源
浏览器再次发送:
GET /style.css
GET /app.js
GET /logo.png
服务器返回资源。
第八步:页面渲染
浏览器:
解析HTML
解析CSS
执行JS
绘制页面
最终显示页面。
十三、完整链路总结
输入URL
↓
DNS解析
↓
获得IP
↓
TCP三次握手
↓
发送HTTP请求
↓
Gin路由匹配
↓
返回HTML
↓
加载CSS/JS/图片
↓
浏览器渲染
↓
页面显示
一句话总结
WebSocket 本质是通过 HTTP 完成协议升级,然后基于 TCP 长连接实现全双工通信;HTTPS 本质是在 HTTP 之上增加 TLS 加密层;浏览器访问网页时会经历 DNS 解析、TCP 三次握手、HTTP 请求响应、资源加载和页面渲染等多个步骤。

![【PBAP】规范精讲[9]: 蓝牙PBAP的互联互通法则——GOEP互操作性要求深度解析-171主机测评](https://www.171host.com/wp-content/uploads/2026/10/20261030152436-6ae4b6b4a87e0-220x150.png)

