> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/contributor/contributor-zh/tong-xin/chuan-shu-lei-xing/websocket.md).

# WebSocket

WebSocket 传输是 Decentraland comms 协议支持的岛屿消息传输方式之一。客户端在从其 realm 的 [Archipelago](https://github.com/decentraland/docs/tree/main/contributor/archipelago/README.md) 服务，或者如果它被标记为固定传输。

在 WebSocket 传输的上下文中，一个岛屿被称为一个 *房间*。这两种叫法指的是同一件事：一组彼此接近、交换更新和聊天的玩家。

连接字符串以 `ws-room:` 前缀开头，后跟一个 `wss://` 指向特定房间的 URI。它们看起来像这样：

```
ws-room:wss://comms.example.com/rooms/<room-id>
```

如果 websocket URI 没有明确的协议， `wss://` 将被假定。

### 连接

该传输通过 HTTPS 使用标准 websocket 协议。客户端可以使用其手头的任何标准实现打开连接。

### WebSocket 数据包

WebSocket 传输中的所有消息都使用 [`WsPacket`](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L78) 结构进行序列化。它们实现了一组协议级的连接与身份验证消息，以及一个用于客户端消息的容器类型。

{% hint style="info" %}
该 [`WsPacket`](#WsPacket) 结构不应与消息 \[`数据包`]\[Packet] 混淆。它是 websocket 传输特有的额外包装层。实际的 comms 消息包含在 [`WsPeerUpdate`](#WsPeerUpdate) 类型中。
{% endhint %}

| 字段   | 类型   | 值                                                                                                                                                                                                                                             |
| ---- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `消息` | `枚举` | <p>以下之一 <code>WsIdentification</code>, <code>WsChallengeRequired</code>, <code>WsSignedChallenge</code>,<br><code>WsWelcome</code>, <code>WsPeerJoin</code>, <code>WsPeerLeave</code>, <code>WsKicked</code> 或 <code>WsPeerUpdate</code>.</p> |

### 认证

在开始向他人转发消息之前，客户端必须通过签名一个挑战字符串来进行身份验证。即使传输 URI 是从 [Archipelago](https://github.com/decentraland/docs/tree/main/contributor/archipelago/README.md) 在先前一轮身份验证之后。

客户端加入一个岛屿时发送的第一条消息是 [`WsIdentification`](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L64)，其中包含一个公开地址。它将收到 [`WsChallengeRequired`](#WsChallengeRequired)，而客户端会发送一个 [`WsSignedChallenge`](#WsSignedChallenge) 作为回复。

```
  .----------.                .--------.
  |  Server  |                | Client |
  '----+-----'                '---+----'
       ⋮                          |
       ⋮                  Connect |
       o - - - - - - - - - - - -|
       |                          |
       |                          |
       |         WsIdentification |
       |<-------------------------+
       +------------------------->|
       | WsChallengeRequired      |
       |                          |
       |                          |
       |        WsSignedChallenge |
       |<-------------------------+
       +------------------------->|
       | WsWelcome                |
       |                          |

```

如果该流程成功完成，客户端将收到一个 [`WsWelcome`](#WsWelcome) 并可以开始向对等方发送消息。

***

**`WsIdentification`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L64)

| 字段   | 类型    | 值                  |
| ---- | ----- | ------------------ |
| `地址` | `字符串` | 客户端的公开 Ethereum 地址 |

***

**`WsChallengeRequired`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L48)

| 字段                  | 类型    | 值                           |
| ------------------- | ----- | --------------------------- |
| `challenge_to_sign` | `字符串` | 由服务器提供、需签名以证明身份的字符串         |
| `already_connected` | `字符串` | 服务器向客户端发出的提示，表示先前的连接可能会被关闭。 |

***

**`WsSignedChallenge`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L56)

| 字段                | 类型    | 值                                                                                                  |
| ----------------- | ----- | -------------------------------------------------------------------------------------------------- |
| `auth_chain_json` | `字符串` | 一个序列化的 [身份验证链](https://github.com/decentraland/docs/tree/main/auth/authchain/README.md) ，并以挑战签名结束。 |

***

**`WsWelcome`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L11)

| 字段                | 类型                    | 值               |
| ----------------- | --------------------- | --------------- |
| `别名`              | `uint32`              | 服务器为客户端会话生成的 ID |
| `peer_identities` | `map<uint32, string>` | 按别名索引的所有当前对等方地址 |

### 连接性

定义了三条消息，用于帮助客户端跟踪其对等方及自身状态。

[`WsPeerJoin`](#WsPeerJoin) 当另一位客户端连接到房间并成功认证时会收到，而 [`WsPeerLeave`](#WsPeerLeave) 当对等方断开连接时会收到。

另外还有 [`WsKicked`](#WsKicked) 消息，它会告知客户端其连接即将被关闭以及原因。按目前的实践，服务器可以将客户端踢出房间的主要原因是：当服务器策略禁止时，他们同时连接到了另一个房间。

***

**`WsPeerJoin`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L19)

| 字段   | 类型       | 值                                         |
| ---- | -------- | ----------------------------------------- |
| `别名` | `uint32` | 在……中发送的服务器生成 ID [`WsWelcome`](#WsWelcome) |
| `地址` | `字符串`    | 新对等方的 Ethereum 地址                         |

***

**`WsPeerLeave`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L27)

| 字段   | 类型       | 值               |
| ---- | -------- | --------------- |
| `别名` | `uint32` | 已断开对等方的服务器生成 ID |

***

**`WsKicked`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L74)

| 字段   | 类型    | 值               |
| ---- | ----- | --------------- |
| `原因` | `字符串` | 服务器对连接将被关闭原因的说明 |

### 客户端消息

要发送 comms 消息 [消息](https://github.com/decentraland/docs/tree/main/contributor/messages/README.md)，客户端会将它们包装在 [`WsPeerUpdate`](#WsPeerUpdate) 结构中。这将传输控制消息类型与对等方之间实际发送的消息区分开来。

```
.-------------------.
| WsPacket          |
|  .--------------. |
|  | WsPeerUpdate | |
|  | .----------. | |
|  | |  Packet  | | |
|  | '----------' | |
|  '--------------' |
'-------------------'

```

***

**`WsPeerUpdate`** [**↗ 源码**](https://github.com/decentraland/protocol/blob/c48ea0aa00d8173084571552463a6a05a7f49636/proto/decentraland/kernel/comms/rfc5/ws_comms.proto#L34)

| 字段           | 类型       | 值                                                                                                |
| ------------ | -------- | ------------------------------------------------------------------------------------------------ |
| `from_alias` | `uint32` | 发送者的服务器生成 ID                                                                                     |
| `body`       | `字节`     | 序列化后的 [消息](https://github.com/decentraland/docs/tree/main/contributor/messages/README.md) 正在被包装的 |
| `不可靠`        | `布尔值`    | 发送者在传递该消息时是优先速度还是可靠性                                                                             |

客户端必须将 `from_alias` 字段设置为 `0` 在发送时，服务器会在将其交付给对等方之前将其填充为正确的标识符。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/contributor/contributor-zh/tong-xin/chuan-shu-lei-xing/websocket.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
