三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

WebSocket、HTTPS 与浏览器访问网页全过程

WebSocket、HTTPS 与浏览器访问网页全过程

一、为什么需要 WebSocket

普通 HTTP 有一个问题:

客户端发请求 ↓ 服务器返回响应 ↓ 连接结束

服务器不能主动给客户端发消息。

例如:

微信聊天 在线客服 股票行情 在线游戏 聊天室

这些场景需要:

服务器主动推送消息

于是出现了:

WebSocket

二、WebSocket 是什么

一句话理解:

WebSocket = HTTP握手 + TCP长连接 + 全双工通信

普通 HTTP:

客户端说一句 服务器回一句

WebSocket:

客户端和服务器一直保持连接 双方随时都能发消息

类似打电话:

HTTP = 发短信 WebSocket = 打电话

三、WebSocket 建立连接全过程

第一步:建立 TCP 连接

前端:

constws=newWebSocket("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 协程

负责接收客户端消息。

goclient.Read()

内部:

for{_,msg,err:=c.Conn.ReadMessage()}

流程:

浏览器 ↓ TCP连接 ↓ Read协程 ↓ ChatServer

Write 协程

负责给客户端推送消息。

goclient.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 对比

特性HTTPWebSocket
连接方式请求响应长连接
是否实时
是否双向
是否保持连接
应用场景网页接口聊天室、游戏

七、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 对比

特性HTTPHTTPS
是否加密
是否安全
默认端口80443
是否需要证书

十一、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:

<linkhref="style.css"><scriptsrc="app.js"></script><imgsrc="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 请求响应、资源加载和页面渲染等多个步骤。

← 返回列表