# 什么是WebSocket？

WebSocket是一种通过HTTP启动的双向、全双工通信协议。通常用于现代Web应用程序中的数据流和其他异步流量。

在这一节，我们将讲解HTTP和WebSocket之间的区别，描述如何建立WebSocket连接，并概述WebSocket消息的结构。

## HTTP与WebSocket有何区别？

大多数Web浏览器和网站之间的通信使用的是HTTP。使用HTTP时，客户端发送请求，服务器返回响应。通常，响应会立即发生，事务就完成了。即使网络连接一直保持打开状态，这种机制也会用于单独的请求和响应事务。

一些新型网站使用的是WebSocket。WebSocket连接是通过HTTP启动的，通常持续时间较长。消息可随时向任何一方发送，并且不具有事务性质。连接通常处于打开和空闲状态，直到客户端或服务器准备好发送消息。

WebSocket在一些特定情况下尤其有用，特别是在需要低延迟或服务器发起消息的场景，例如实时的金融数据流。

## 如何建立WebSocket连接？

WebSocket连接通常使用客户端JavaScript创建，如下所示：

```javascript
var ws = new WebSocket("wss://normal-website.com/chat");
```

> **注意**
>
> `wss`协议通过加密的TLS连接建立WebSocket，而`ws`协议则使用未加密的连接。

为了建立连接，浏览器和服务器通过HTTP进行WebSocket握手。浏览器发起的WebSocket握手请求如下：

```http
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket


```

如果服务器接受连接，就会返回类似如下的WebSocket握手响应：

```http
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
```

此时，网络连接保持打开，并且可以用于向任何一方发送WebSocket消息。

> **注意**
>
> WebSocket握手消息有几个特性值得注意：
>
> * 请求和响应中的`Connection`和`Upgrade`标头表明这是一个WebSocket握手。
> * `Sec-WebSocket-Version`请求标头指定客户端希望使用的WebSocket协议版本。通常是`13`。
> * `Sec-WebSocket-Key`请求标头包含一个Base64编码的随机值，该值应在每次握手请求中随机生成。
> * `Sec-WebSocket-Accept`响应标头包含一个哈希值，该哈希值是由`Sec-WebSocket-Key`请求标头中的值与协议规范中定义的特定字符串拼接并哈希而成。这样做是为了防止因服务器或缓存代理配置错误而产生的误导性响应。

## WebSocket消息长什么样？

一旦建立了WebSocket连接，客户端或服务器就可以在任何一方异步发送消息。

可以使用客户端JavaScript从浏览器发送类似如下这样简单的消息：

```javascript
ws.send("Peter Wiener");
```

原则上，WebSocket消息可以包含任何内容或数据格式。在现代应用程序中，往往使用JSON在WebSocket消息中发送结构化数据。

例如，使用WebSocket的聊天机器人应用程序可能会发送如下消息：

```json
{"user":"Hal Pline","content":"I wante to be a Playstation growing up, not a device to answer your inane questions"}
```
