学习websocket的部分总结

一:websocket的特性

WebSocket 是一种先进的通信协议,提供了客户端和服务器之间的全双工、低延迟、实时通信通道。以下是 WebSocket 的主要特性:

  1. 全双工通信

    特性:WebSocket 允许客户端和服务器之间的双向通信,可以同时发送和接收数据。
    优势:减少了网络延迟,提高了数据传输效率,适合实时应用,如在线游戏、实时聊天、股票交易等。

  2. 持久连接

    特性:WebSocket 连接一旦建立,可以持续保持,直到一方主动关闭连接。
    优势:避免了 HTTP 轮询的频繁连接开销,降低了服务器和客户端的资源消耗。

  3. 低开销

    特性:WebSocket 连接建立后,后续数据传输不再需要附带 HTTP 头信息,开销较小。
    优势:数据帧结构简单,传输效率高,适合高频率、小数据量的实时传输。

  4. 实时性

    特性:WebSocket 可以在事件发生时立即推送消息,而不需要客户端主动请求。
    优势:显著提高了数据传输的实时性,用户体验更加流畅。

  5. 安全性

    特性:WebSocket 支持加密传输(wss://),确保数据在传输过程中的安全性。
    优势:防止数据在传输过程中被窃听或篡改,适合对安全性要求较高的应用场景。

  6. 简单的 API

    特性:WebSocket API 简单易用,主要包括打开连接、发送消息、接收消息和关闭连接四个基本操作。
    优势:开发者可以快速上手,实现复杂的实时通信功能。

  7. 心跳机制

    特性:WebSocket 支持心跳检测机制,确保连接的活跃性。
    优势:及时发现和处理连接断开的问题,保持连接的可靠性。

  8. 二进制和文本数据传输

    特性:WebSocket 支持传输二进制数据和文本数据。
    优势:可以满足不同类型的数据传输需求,如图片、视频、音频等。

  9. 浏览器兼容性

    特性:主流浏览器均支持 WebSocket 协议。
    优势:可以在各种浏览器环境下使用,适应性强,应用范围广泛。

  10. 协议支持

    特性:WebSocket 是一种标准协议,具有良好的兼容性和可扩展性。
    优势:可以与其他网络协议无缝集成,扩展能力强,适应各种复杂的网络应用场景。

示例代码
服务端(Go 语言)

go

package main

import (
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func handler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer conn.Close()

    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            log.Println(err)
            return
        }
        if err := conn.WriteMessage(messageType, p); err != nil {
            log.Println(err)
            return
        }
    }
}

func main() {
    http.HandleFunc("/ws", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

客户端(JavaScript)

javascript

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

socket.onopen = function(e) {
  console.log("[open] Connection established");
  socket.send("Hello Server!");
};

socket.onmessage = function(event) {
  console.log(`[message] Data received from server: ${event.data}`);
};

socket.onclose = function(event) {
  if (event.wasClean) {
    console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
  } else {
    console.log('[close] Connection died');
  }
};

socket.onerror = function(error) {
  console.log(`[error] ${error.message}`);
};
总结

WebSocket 的全双工通信、持久连接、低开销和实时性等特性,使其非常适合需要实时数据传输的应用场景。通过 WebSocket,可以大幅提高数据传输的效率和用户体验,在现代 Web 应用中得到了广泛的应用。

二:WebSocket 请求方式

WebSocket 请求并不完全是一个传统的 HTTP 请求,虽然它使用 HTTP 协议进行握手,但它并不遵循 GET、POST 等传统的 HTTP 方法。WebSocket 握手请求看起来类似于一个 HTTP GET 请求,但它有一些特定的头信息来启动 WebSocket 连接。

1、WebSocket 握手过程

客户端发起一个类似于 HTTP GET 请求的握手请求,其中包含一些特殊的头字段:
Upgrade: websocket 表示请求升级到 WebSocket 协议。
Connection: Upgrade 表示升级连接。
Sec-WebSocket-Key 是一个 Base64 编码的随机密钥,用于安全验证。
Sec-WebSocket-Version 表示 WebSocket 协议版本(一般为 13)。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
2、服务器响应握手请求:

服务器收到握手请求后,检查请求头字段是否符合 WebSocket 协议的要求。如果符合,会返回一个 101 Switching Protocols 的响应,表示协议切换成功:
Upgrade: websocket 表示确认升级到 WebSocket 协议。
Connection: Upgrade 表示确认升级连接。
Sec-WebSocket-Accept 是根据客户端的 Sec-WebSocket-Key 生成的一个校验值,用于验证握手请求的合法性。
示例握手响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
3、建立 WebSocket 连接:

握手成功后,客户端和服务器之间的连接正式升级为 WebSocket 连接。在这个连接上,客户端和服务器可以相互发送和接收消息,不再使用 HTTP 协议,而是使用 WebSocket 协议进行全双工通信。

总结

WebSocket 握手仅在连接建立时使用 HTTP 协议,握手成功后,通信完全使用 WebSocket 协议进行全双工的消息传输。

三、websockt双全工通信的消息格式大概是什么样子的?心跳帧的内容又是什么样子的?

WebSocket 使用帧(frame)来传输数据,每个帧都有自己的结构和格式。下面是 WebSocket 帧的结构和心跳帧的内容。

WebSocket 帧结构

WebSocket 帧的格式如下:
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| OP   |M| PAYLOAD LEN          |    EXTENDED PAYLOAD LENGTH    |
|I|S|S|S| CODE |A|                       | (if PAYLOAD LEN==126/127)     |
|N|V|V|V|      |S|                       |                               |
| |1|2|3|      |K|                       +-------------------------------+
| | | | |      | |                       |     EXTENDED PAYLOAD LENGTH   |
| | | | |      | |                       |        (if PAYLOAD LEN==127)  |
| | | | |      | |                       +-------------------------------+
| | | | |      | |                       |  MASKING KEY (if MASK==1)     |
| | | | |      | |                       +-------------------------------+
| | | | |      | |                       |          PAYLOAD DATA         |
| | | | |      | |                       +-------------------------------+
| | | | |      | |                       |        PAYLOAD DATA           |
| | | | |      | |                       +-------------------------------+
| | | | |      | |                       |        PAYLOAD DATA           |
| | | | |      | |                       +-------------------------------+

字段说明:
FIN (1 bit): 表示是否是消息的最后一帧。1 表示是,0 表示还有后续帧。
RSV1, RSV2, RSV3 (3 bits): 保留位,通常为 0,除非双方协议另有约定。
Opcode (4 bits): 表示帧的类型。常见的值有:

0x0 (继续帧)
0x1 (文本帧)
0x2 (二进制帧)
0x8 (关闭帧)
0x9 (Ping 帧)
0xA (Pong 帧)

Mask (1 bit): 表示是否对负载数据进行了掩码处理。客户端到服务器的消息需要掩码。
Payload length (7 bits, 7+16 bits, 7+64 bits): 表示负载数据的长度。

0-125 表示数据的直接长度。
126 表示使用 16 位无符号整数来表示长度。
127 表示使用 64 位无符号整数来表示长度

Masking key (0 or 4 bytes): 如果 Mask 为 1,则包含 4 字节的掩码键。
Payload data (x bytes): 实际传输的数据。长度由 Payload length 指定。

心跳帧(Ping/Pong 帧)

WebSocket 使用 Ping/Pong 帧来保持连接活跃,检测对方是否在线。这是一种心跳机制。

Ping 帧:
Opcode: 0x9

服务器或客户端发送 Ping 帧对方以检测连接。
通常包含负载数据,但不是必须的。

Pong 帧:
Opcode: 0xA

收到 Ping 帧的一方必须回复 Pong 帧。
Pong 帧可以包含与 Ping 帧相同的负载数据,也可以为空。

总结

1、帧结构:WebSocket 使用帧来传输数据,每个帧包含控制信息和负载数据。

2、心跳机制:Ping/Pong 帧用于检测连接的活跃状态,防止连接因长时间未使用而被关闭。

3、消息格式:WebSocket 的消息可以是文本或二进制数据,由帧头的 Opcode 指定。

  • 56
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值