> 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/blob/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 %}

| 字段        | 类型   | 值                                                                                                                                                                                                                                              |
| --------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message` | `枚举` | <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/blob/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) 作为回复。

```
  .----------.                .--------.
  |  服务器  |                | 客户端 |
  '----+-----'                '---+----'
       ⋮                          |
       ⋮                  连接 |
       o - - - - - - - - - - - - -|
       |                          |
       |                          |
       |         WsIdentification |
       |<-------------------------+
       +------------------------->|
       | WsChallengeRequired      |
       |                          |
       |                          |
       |        WsSignedChallenge |
       |<-------------------------+
       +------------------------->|
       | WsWelcome                |
       |                          |

```

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

***

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

| 字段        | 类型    | 值                  |
| --------- | ----- | ------------------ |
| `address` | `字符串` | 客户端的公开 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/blob/main/auth/authchain/README.md) ，其结束于挑战签名。 |

***

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

| 字段                | 类型                    | 值               |
| ----------------- | --------------------- | --------------- |
| `别名`              | `无符号32位整数`            | 服务器为客户端会话生成的 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)

| 字段        | 类型         | 值                                       |
| --------- | ---------- | --------------------------------------- |
| `别名`      | `无符号32位整数` | 中发送的服务器生成的 ID [`WsWelcome`](#WsWelcome) |
| `address` | `字符串`      | 新同伴的 Ethereum 地址                        |

***

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

| 字段   | 类型         | 值                |
| ---- | ---------- | ---------------- |
| `别名` | `无符号32位整数` | 断开连接的同伴的服务器生成 ID |

***

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

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

### 客户端消息

要发送 comms [消息](https://github.com/decentraland/docs/blob/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` | `无符号32位整数` | 发送者的服务器生成 ID                                                                                        |
| `body`       | `字节`       | 已序列化的 [message](https://github.com/decentraland/docs/blob/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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
