在现代 Web 开发中,实时通信越来越重要。传统的 HTTP 协议是基于请求/响应模型的,即客户端每次向服务器发送请求时,服务器才会回应。而 WebSocket 协议是一个全双工、持久的通信协议,允许客户端和服务器在同一个连接上进行实时双向数据传输。本文将详细讲解 WebSocket 客户端与服务端的连接过程,帮助你更好地理解如何实现实时通信。

什么是 WebSocket?

WebSocket 是一种基于 TCP 的协议,旨在提供一个持久的、双向的通信通道。不同于传统的 HTTP 协议,WebSocket 连接是持续存在的,这意味着一旦建立了连接,客户端和服务器可以随时相互发送消息,而不需要每次都建立新连接。

WebSocket 的最大优势在于,它支持双向通信,即客户端和服务器可以在任何时候进行数据交换,而无需等到请求被发送或接收。这使得 WebSocket 特别适用于在线聊天、股票实时更新、在线游戏等需要低延迟和高频次消息传递的应用场景。

WebSocket 客户端与服务器连接过程

WebSocket 的连接过程分为几个关键步骤,下面我们逐一讲解:

1. 客户端发起 WebSocket 握手请求

WebSocket 连接的建立从客户端发起。当客户端希望与服务器建立 WebSocket 连接时,它会首先发送一个 HTTP 请求,请求升级到 WebSocket 协议。这个请求类似于普通的 HTTP 请求,但它包含了一些特殊的头信息。

客户端请求示例
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

关键字段:

  • Upgrade: websocket:告知服务器,客户端希望将当前的 HTTP 连接升级为 WebSocket 连接。
  • Connection: Upgrade:表示客户端请求进行协议升级。
  • Sec-WebSocket-Key:客户端生成的一个随机字符串,服务器用这个字符串生成响应。
  • Sec-WebSocket-Version:指定 WebSocket 的版本,通常是 13

2. 服务器响应 WebSocket 握手请求

服务器接收到客户端的 WebSocket 握手请求后,会验证客户端的请求是否合法。如果服务器支持 WebSocket 协议,它会返回一个 HTTP 101 Switching Protocols 响应,表示协议已成功升级。

服务器响应示例
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYG1t4pJd5P3+OGzXqVsM8YzA6jXXM=

关键字段:

  • HTTP/1.1 101 Switching Protocols:表示服务器同意升级协议。
  • Upgrade: websocket:表示服务器同意进行 WebSocket 协议升级。
  • Sec-WebSocket-Accept:服务器基于客户端的 Sec-WebSocket-Key 字段计算出的一个响应值,用于确保请求的合法性。

此时,WebSocket 握手完成,客户端和服务器之间的连接已经成功升级为 WebSocket 连接。

3. 建立 WebSocket 连接

一旦握手成功,WebSocket 连接就建立起来了。此时,客户端和服务器之间的连接是双向的,双方可以随时发送和接收消息,而无需再发送 HTTP 请求或响应。WebSocket 的通信模式非常高效,适合实时应用。

客户端与服务器通信示例
客户端代码(JavaScript 示例)

在客户端,你可以使用 JavaScript 的 WebSocket API 来创建和管理 WebSocket 连接:

// 创建 WebSocket 连接
let socket = new WebSocket('ws://example.com/chat');

// 连接成功时触发
socket.onopen = function(event) {
    console.log('WebSocket is connected');
    // 发送消息到服务器
    socket.send('Hello, server!');
};

// 接收到服务器消息时触发
socket.onmessage = function(event) {
    console.log('Received message from server: ' + event.data);
};

// 连接关闭时触发
socket.onclose = function(event) {
    console.log('WebSocket connection closed');
};

// 连接错误时触发
socket.onerror = function(event) {
    console.error('WebSocket error:', event);
};
服务器代码(Java 示例)

在服务器端,我们可以使用 Java 的 WebSocket API 来实现 WebSocket 服务端。以下是一个简单的 WebSocket 服务端代码示例:

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/chat")
public class WebSocketServer {

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("Client connected: " + session.getId());
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        System.out.println("Received message: " + message);
        // 发送消息回客户端
        session.getAsyncRemote().sendText("Hello from server");
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("Client disconnected: " + session.getId());
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }
}

展开

在上述代码中,@OnOpen@OnMessage@OnClose 和 @OnError 是 WebSocket 服务端处理连接、消息、关闭和错误的注解。客户端连接到 /chat 端点时,服务端会处理消息并返回响应。

4. WebSocket 连接关闭

当通信完成后,客户端或服务器可以主动关闭连接。关闭连接时,WebSocket 协议通过发送一个 关闭帧 来进行连接的优雅断开。

客户端关闭连接
// 关闭 WebSocket 连接
socket.close();
服务器关闭连接
session.close();

关闭连接时,客户端和服务器都会收到连接关闭的通知。

总结

WebSocket 协议提供了高效的双向实时通信能力,非常适合用于需要频繁数据交换的场景,如在线聊天、股票实时更新、在线游戏等。其连接过程简洁而高效,客户端通过 HTTP 发起握手请求并升级协议,服务器响应后建立 WebSocket 连接,双方即可进行实时数据传输。

通过 WebSocket,客户端和服务器之间的通信变得更为流畅,消除了传统 HTTP 请求中不断建立和断开连接的开销,为实时应用提供了更好的支持。

希望通过这篇文章,你对 WebSocket 的连接过程有了更清晰的理解,并能够在自己的项目中应用这一强大的技术。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐