哥们 你值得拥有的 WebSocket 全面详解(超通俗+实用版)

926 阅读5分钟

好兄弟,来来来,我来给你整一份WebSocket 超详细通俗易懂+动图+代码实战全套讲解!跟着这份学,保你彻底搞懂 WebSocket 是啥,怎么用,和 HTTP 有啥区别。


📖 WebSocket 全面详解(超通俗+实用版)


📌 WebSocket 是什么?

👉 WebSocket 是一种基于 TCP 的全双工通信协议
👉 浏览器和服务器之间可以相互主动发送消息
👉 它是为了解决 HTTP 单向、频繁请求的弊端 诞生的。

简单说:
🚀 HTTP:客户端请求,服务器被动响应
🚀 WebSocket:客户端、服务器随时互相发消息


📊 WebSocket 和 HTTP 区别

对比项HTTPWebSocket
连接方式请求-响应,单向通信全双工,双向实时通信
连接是否保持请求一次,断开一次一次连接,持续保持
通信效率每次都要建立连接,开销大一次连接,多次通信,效率高
场景普通网页、API 接口、表单提交聊天室、实时推送、游戏、直播

📊 WebSocket 工作流程图

👇 超清晰流程:

① 客户端 发起 WebSocket 握手(特殊 HTTP 请求)
② 服务器 响应协议切换(101 Switching Protocols)
③ 建立 WebSocket 长连接(全双工)
④ 双方随时互相发送消息
⑤ 断开时关闭连接

📦 WebSocket 报文结构

字段说明
头部 (2 字节)是否结束、是否掩码、长度
掩码 (4 字节)防止劫持(客户端→服务端)
数据载荷真正传输的数据内容

👉 比 HTTP 更小巧,实时性更强!


📚 WebSocket 实战演示(Java + JS)

🌍 服务端(Spring Boot + WebSocket)

@ServerEndpoint("/ws/{userId}")
@Component
public class WebSocketServer {
    private static Map<String, Session> sessionMap = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        sessionMap.put(userId, session);
        System.out.println(userId + " connected!");
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("Message: " + message);
    }

    @OnClose
    public void onClose(Session session, @PathParam("userId") String userId) {
        sessionMap.remove(userId);
        System.out.println(userId + " disconnected!");
    }
}

🌐 前端(JS 客户端)

const ws = new WebSocket("ws://localhost:8080/ws/123");

ws.onopen = () => {
  console.log("连接成功!");
  ws.send("Hello Server!");
};

ws.onmessage = (event) => {
  console.log("收到消息:" + event.data);
};

ws.onclose = () => {
  console.log("连接关闭!");
};

🎨 WebSocket 动图演示

我给你画了👇这张:

websocket 动图转存失败,建议直接上传图片文件
👉 实时双向通道,随时互发消息。


📌 WebSocket 使用场景

✅ 实时聊天系统(IM)
✅ 实时推送(股票、新闻、物流)
✅ 在线游戏
✅ 实时协作(协作文档、代码)
✅ 实时直播弹幕


🎯 总结一句话:

WebSocket 就是个双向实时通信的专用通道,适合高频互动、低延迟场景,补上了 HTTP 单向短连接的短板。



📦 WebSocket 传输的到底是啥?

👉 WebSocket 传输的是帧(frame) ,每个帧里包含:

  • 控制信息(帧头)
  • 真实数据(载荷)

载荷数据可以是

  • 文本(字符串)
  • 二进制(Binary)

也就是说:

WebSocket 既可以传文本,也可以传二进制数据


📊 传输二进制的方式有两种

在 WebSocket 中,二进制常见两种格式:

格式说明
Blob二进制大对象(比如图片、音频、文件流)
ArrayBuffer纯二进制内存缓冲区(比如自定义协议、音视频数据)

🌐 举个前端发送二进制的例子:

const ws = new WebSocket("ws://localhost:8080/ws");

// 设置二进制类型
ws.binaryType = "arraybuffer";

// 发送二进制
const buffer = new ArrayBuffer(8); // 分配8字节
ws.send(buffer);

👉 服务端直接接收二进制流解析就行。


🎨 WebSocket 报文结构(简化版)

字段长度说明
FIN1 bit是否是最后一帧
Opcode4 bit数据类型(文本、二进制)
Payload Length7-64 bit数据长度
Masking-key0/4 字节客户端到服务端必有
Payload dataN 字节真正数据(二进制 or 文本)

👉 Opcode 决定了数据类型:

  • 0x1:文本帧
  • 0x2:二进制帧

✅ 总结一句:

WebSocket 是按帧传输的,既支持文本,也支持二进制,并且因为无多余 HTTP 头,开销小,效率高。


📌 应用场景示例

传文本

  • 聊天消息
  • 实时通知
    传二进制
  • 图片、音视频流
  • 自定义协议(压缩二进制结构)
  • 实时文件传输

好兄弟!这个问题问得特别到位,长连接和短连接 是后端网络通信、WebSocket、HTTP、数据库、消息队列里经常涉及的概念,咱来一波超详细、超通俗、超清晰的讲解,彻底搞懂它们的区别和应用场景。



📖 长连接 vs 短连接 全面详解


📌 概念对比

🔗 短连接(Short Connection)

👉 每次通信都要重新建立 TCP 连接,数据发送完成后就立即关闭连接

  • 例如:HTTP 1.0、普通数据库请求、一次性 API 调用。

流程:

客户端:建立连接 → 发送请求 → 接收响应 → 关闭连接

🔗 长连接(Long Connection)

👉 建立一次 TCP 连接,通信完成后不关闭,保持连接状态,可以复用同一个连接发送多次数据

  • 例如:WebSocket、HTTP 1.1 keep-alive、长轮询、Netty、MySQL 长连接。

流程:

客户端:建立连接 → 发送请求 → 接收响应 → 保持连接 → 继续通信或关闭

📊 图示区别

我给你画一下👇:

📎 短连接:

[建立连接] -> [发送请求] -> [接收响应] -> [关闭连接]
[建立连接] -> [发送请求] -> [接收响应] -> [关闭连接]
...

📎 长连接:

[建立连接] -> [多次发送请求] -> [多次接收响应] -> [关闭连接]

📦 应用场景

类型应用场景示例
短连接低频请求、临时性调用、一次性交互普通 HTTP 接口、图片下载、表单提交
长连接高频实时交互、持续通信WebSocket 聊天、长轮询、直播、游戏、消息推送

🛠️ 优缺点分析

📌 短连接

✅ 优点:

  • 资源占用少(连接用完即关)
  • 实现简单

❌ 缺点:

  • 建立/关闭连接频繁,开销大
  • 延迟高

📌 长连接

✅ 优点:

  • 减少 TCP 三次握手/四次挥手次数
  • 实时性强,延迟低
  • 适合高频互动场景

❌ 缺点:

  • 长时间占用资源
  • 心跳检测、超时断连管理麻烦(心跳机制、断线重连)

📚 实例对比

📎 HTTP 1.0 短连接

GET /api/data HTTP/1.0
→ 建立连接
→ 发送请求
→ 响应完就断开

📎 HTTP 1.1 长连接

GET /api/data HTTP/1.1
Connection: keep-alive
→ 建立连接
→ 多次请求复用同一个连接
→ 空闲或超时再断开

📎 WebSocket 长连接

→ 建立 WebSocket 连接
→ 双向实时通信,持续保持
→ 任何一方主动关闭才断开

✅ 总结一句话:

短连接:用完即断,适合临时性、低频操作

长连接:保持不断,适合高频、实时、互动场景