websocket和http区别
websocket和http的基本区别
一句话核心总结
HTTP 是单向请求 - 响应的短连接协议(一问一答),WebSocket 是全双工持久长连接协议(双方随时互发消息,实时通信)。
核心区别对比
- 通信模式
- HTTP:半双工,客户端主动请求→服务端响应,服务端不能主动推数据,无请求就无交互。
- WebSocket:全双工,客户端服务端地位对等,双方可随时主动收发消息。
- 连接生命周期
- HTTP:默认短连接,一次请求响应后立马断开;HTTP1.1 长连接也只是复用链路,仍是问答模式。
- WebSocket:握手后建立持久 TCP 长连接,通道一直保持,直到主动关闭 / 网络中断。
- 开销与性能
- HTTP:每次请求带 Header、Cookie 等冗余头部,轮询 / 长轮询开销大,实时性差。
- WebSocket:连接建立后头部极简,数据帧轻量化,极低开销,高并发实时传输更优。
- 底层与端口
- HTTP:基于 TCP,默认 80/443 端口。
- WebSocket:先借 HTTP 完成握手(兼容 80/443),握手成功后协议升级为 ws/wss,仍基于 TCP。
- 适用场景
- HTTP:绝大多数普通网页接口、文件下载、查询提交等一次性请求交互场景。
- WebSocket:聊天室、实时对战游戏、股票行情、设备状态推送、在线协同编辑等高实时双向通信场景。
补充小知识点
WebSocket 初始握手是HTTP 协议,通过Upgrade: websocket请求头完成协议切换,完美兼容现有 web 服务架构。
websocket的原理
一、底层基础定位
WebSocket 是基于 TCP 传输层、专为浏览器 / 服务端全双工实时通信设计的应用层协议;核心兼容设计:握手阶段复用 HTTP/HTTPS 完成协商,握手成功后彻底脱离 HTTP 协议,升级为独立 ws/wss 长连接通道,全程依托 TCP 可靠传输(有序、无丢包、重传机制)。
- 明文:ws:// 默认同 HTTP 80 端口
- 密文:wss:// 默认同 HTTPS 443 端口(生产环境首选,防劫持加密)
二、完整核心工作流程(四大阶段)
阶段 1:客户端发起 HTTP 协商握手(核心升级请求)
浏览器主动发送标准 HTTP GET 请求,携带专属升级请求头,告知服务端:我要把这条 TCP 连接升级成 WebSocket 协议。关键请求头必带:
GET /ws/connect HTTP/1.1 Host: xxx.com Upgrade: websocket // 声明要升级为WebSocket协议 Connection: Upgrade // 标记连接升级意向 Sec-WebSocket-Key: 随机Base64密钥串 // 客户端随机生成,防恶意伪造握手 Sec-WebSocket-Version: 13 // WebSocket标准协议版本(固定13) Origin: 跨域校验源阶段 2:服务端响应 HTTP 握手确认
服务端校验请求头合法后,返回101 Switching Protocols状态码(协议切换专属状态码),完成握手应答:
- 把客户端的
Sec-WebSocket-Key拼接固定魔数字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11 - 做 SHA1 加密后再 Base64 编码,生成应答密钥放入
Sec-WebSocket-Accept返回关键响应头:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: 服务端演算后的密钥串✅ 校验匹配成功:TCP 链路永久保留,彻底告别 HTTP 格式,协议正式切换为 WebSocket;❌ 校验失败:直接拒绝连接,断开 TCP。
阶段 3:全双工长连接数据帧传输(核心通信阶段)
握手完成后不再有 HTTP 冗余 Header,双方以轻量化二进制数据帧(Frame)双向自由收发数据,真正全双工:客户端发服务端收、服务端主动推客户端收互不阻塞。
- 数据帧极简结构:极小头部开销,相比 HTTP 每次带全套 Header,带宽损耗极低,高并发性能极强
- 传输内容支持:文本帧、二进制帧、关闭帧、心跳 ping/pong 控制帧等
- 无请求应答绑定:不用客户端轮询请求,服务端可随时主动推送业务数据(实时核心优势)
阶段 4:连接关闭 / 保活机制
- 正常关闭:任意一方发送关闭控制帧,协商后优雅断开 TCP 连接
- 异常断连:网络波动、服务重启、浏览器关闭直接断链
- 心跳保活(生产必备):TCP 本身无应用层保活,防火墙 / 代理会静默释放空闲长连接;约定定时发
ping帧,对方立刻回pong帧,检测连接存活,无效则重连。
三、关键核心特性原理
- 同源与跨域处理WebSocket 握手基于 HTTP,自带 Origin 跨域校验,服务端可配置允许 / 拒绝跨域连接,安全可控。
- 数据可靠性依托底层 TCP 天生特性:数据有序到达、丢失自动重传、无差错传输,不用上层自己处理丢包乱序。
- 协议无状态连接通道是持久的,但协议本身无业务状态,业务会话需自己绑定标识(如握手带 token 鉴权)。
四、和 HTTP 长连接本质区别厘清
HTTP1.1 的 Keep-Alive 只是复用 TCP 链路,依然遵守「客户端请求→服务端应答」一问一答模式,服务端绝对不能主动推数据;WebSocket 是协议彻底升级,TCP 通道独占全双工,通信模式完全自由,是真正意义的实时长连接。
五、生产环境底层小补充
Nginx / 网关反向代理 WebSocket 时,必须配置转发 Upgrade、Connection 请求头,否则握手会失败;同时调大网关长连接超时时间,配合业务心跳保障连接稳定。
websocket和http的根本区别
直接挖到内核规则 + 收发代码行为 + 协议封装细节,一步步告诉你:TCP 原生自由在哪 → HTTP 怎么给 TCP 套枷锁锁死主动发 → WebSocket 怎么拆掉枷锁释放自由,全讲透实现原理。
第一层:先看清裸 TCP 的真实形态(本来的自由状态)
TCP 是传输层套接字 Socket,操作系统原生接口就两个极致自由的能力:
socket.read() // 随时读对面发来的数据 socket.write() // 随时往对面发数据,想写就写,不用等对方请示✅TCP 真正规则:两端 Socket 完全对等,全双工无约束,你想读就读、想写就写,随时自由收发,没有任何 “必须你先发我才能回” 的规矩这是操作系统内核给的底层自由,天生就支持服务器随便主动 write 发数据给客户端。
第二层:HTTP 是怎么亲手给 TCP 套上「死枷锁」的?(核心实现逻辑)
HTTP 是应用层协议契约,它在裸 TCP Socket 之上,强行定了一套严格收发编程规则,把自由锁死了:
1. HTTP 客户端代码固定行为
客户端必须主动先调用 socket.write ()往 TCP 里发完整 HTTP 请求报文(Method/Url/Header/Body),不先发请求,就绝不读也不写。
2. HTTP 服务端代码强制死逻辑(枷锁核心)
服务端监听 TCP Socket 后,执行铁顺序:
- 死循环阻塞先 socket.read () 读客户端的完整 HTTP 请求
- 解析请求报文,业务处理
- 严格对应这次请求,调用 socket.write () 写出唯一一次 HTTP 响应报文
- 写完响应,立刻终止本次对话;哪怕 Keep-Alive 复用 TCP 连接,也只会回到第一步:继续阻塞等下一个客户端新请求
划死本质枷锁规则(代码级强制)
HTTP 服务端代码逻辑里:绝对不允许、也不设计「无请求触发时主动 socket.write () 发数据」的逻辑不是 TCP 不让发,是HTTP 协议约定 + 服务端代码架构,彻底禁止主动 write,强行做成「一问一答串行绑定模型」。
补充:HTTP1.1 Keep-Alive 只是小改良,枷锁没拆
只是 TCP 连接不关闭、不用反复建连,但是收发逻辑没变:依然必须客户端先发新请求 → 服务端才允许回响应,服务端依旧不能凭空主动 write 推送,枷锁完好无损。
第三层:WebSocket 又是怎么彻底拆掉枷锁、释放 TCP 自由的?分步实现
核心两步:HTTP 过渡握手 → 抛弃 HTTP 契约,切换回裸 TCP 自由读写模型
步骤 1:借用 HTTP 完成一次合规握手(只为兼容 80/443 端口、过防火墙)
客户端先发标准 HTTP 升级请求:带Upgrade:websocket头服务端校验密钥合法,返回101 Switching Protocols响应
👉 关键动作发生在服务端程序内部:握手完成瞬间,代码直接废掉所有 HTTP 请求 - 响应循环逻辑,不再遵守 HTTP 收发规则
步骤 2:协议切换,回归 TCP 原生 Socket 自由读写模型(彻底拆枷锁)
切换后两端代码逻辑彻底变了:不再有「先读请求→再写对应响应」的绑定死流程!两端各自维护独立的读写通道:
- 服务端随时想推数据:直接拿 TCP Socket 句柄随意调用 socket.write () 发 WebSocket 数据帧,不需要等客户端任何请求
- 客户端随时发消息:自己 socket.write () 写帧就行
- 两边异步互相读数据流,完全解放 TCP 全双工天性
额外封装:只加极轻的 WebSocket 帧头,不锁规则
WebSocket 只是给 TCP 流包个极小的数据帧 Header(标识文本 / 二进制 / 心跳帧),纯粹做数据格式化,绝不限制收发顺序、绝不强制请求应答关系,完全不束缚 Socket 自由读写。
终极一句话代码对照,看懂就彻底通透
1. HTTP 服务端伪代码(枷锁版)
while(true){ req = socket.read() // 必须死等客户端先请求 res = handle(req) socket.write(res) // 只能对应请求写一次响应,绝不能乱主动发 }2. WebSocket 服务端伪代码(解放版)
// 读线程:异步随时读客户端消息 new Thread(()=>{ while(true){ readFrame(); } }) // 写线程/业务触发:想推就直接write,无任何等待 public void pushMsg(data){ socket.write(websocketFrame(data)); }总结闭环:TCP 天生自由读写 → HTTP 应用层代码强行约定串行问答锁死主动 write → WebSocket 握手后丢弃 HTTP 问答契约,回归 Socket 原生自由收发,仅此而已。
