> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 执行事件与 WebSocket 设置

## 概述

[执行事件(Execution Events)](/zh/execution-events)和 [WebSocket](/zh/reference/json-rpc/overview) 功能是相互配合设计的,目的是让 Monad 对高负载应用更加快速。执行事件是一个底层系统,而 WebSocket 支持是该系统的一种具体应用。

### 执行事件

[执行事件](/zh/execution-events)为开发者提供了监听 Monad 区块链实时数据时性能最高的选项。

* 执行事件使用共享内存通信系统,这需要额外的设置,本页对此进行了描述。此设置不是默认安装步骤的一部分;只有在运行使用执行事件功能的实时数据消费者时才需要它。

* 通信的"共享内存"特性意味着执行事件的消费者必须与 Monad 节点运行在同一主机上,才能观察到主机内存中的实时数据。

* Monad 的 RPC 服务器可以选择性地使用执行事件以获得更好的性能,并支持某些功能,即 `eth_subscribe` JSON-RPC 调用。

<Note>
  [此处](/zh/monad-arch/realtime-data/data-sources)提供了 Monad 中所有实时数据方案的概览。[此处](/zh/execution-events)是编写消费执行事件程序的教程。
</Note>

### WebSocket

在 Monad 的 JSON-RPC 服务器中,WebSocket 有两种用途:

* 建立持久连接以发起 JSON-RPC 请求
* 能够调用 `eth_subscribe` API,该 API 会在新的实时数据发生时"推送"数据,因此您无需轮询新事件

必须通过命令行参数 `--ws-enabled` 在 RPC 服务器中显式启用 WebSocket 支持。当传入 `--ws-enabled` 时,主机必须已配置为支持执行事件,否则 RPC 将以错误退出。

Monad 上 WebSocket 的用户指南可在[此处](/zh/reference/json-rpc/overview)查阅。

## 要求

* 一个运行中的 Monad 全节点([安装说明](/zh/node-ops/full-node-installation))
* 一个 `hugetlbfs` 文件系统挂载点
  * 可以使用 `hugeadm` 工具进行设置;示例见下文
* `RPC` 和 `Execution` 两者的自定义(即"覆盖")`systemd` 单元文件
  * 示例均见下文

## 使用 `hugeadm` 设置 `hugetlbfs` 挂载点

### 通用前置条件

安装所需的软件包:

```bash theme={null}
sudo apt install libhugetlbfs-bin
```

### 执行事件 SDK 前置条件

如果您希望在自己的软件中使用执行事件 SDK 消费实时数据,则必须额外安装以下软件包:

```bash theme={null}
sudo apt install libhugetlbfs-dev libhugetlbfs0 libzstd-dev
```

这些仅对 SDK 是必需的;如果您只需要在 RPC 服务器中启用 WebSocket 支持,则\_不需要\_这些软件包。

### CLI 一次性设置

<Warning>
  此配置仅用于一次性测试,重启后**不会**保留
</Warning>

```bash theme={null}
# NOTE: here we use `monad` but if you are running as a custom user, that should be set here
$ sudo hugeadm --create-user-mounts monad
```

### 示例 `systemd` 单元文件

这样可以让挂载点在重启后仍然保持。

创建服务文件:

```bash theme={null}
sudo nano /etc/systemd/system/events-hugepages-mounts.service
```

粘贴以下内容:

```ini theme={null}
# NOTE: as mentioned above, you can change the `monad` user to your custom user (if needed)
[Unit]
Description=Create hugepage mounts for monad
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/bin/hugeadm --create-user-mounts monad
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```

保存并退出(`Ctrl+O`、`Enter`、`Ctrl+X`)。

启用并启动服务:

```bash theme={null}
sudo systemctl daemon-reload
sudo systemctl enable --now events-hugepages-mounts
```

### 创建 event-rings 目录

WebSocket 事件正常工作需要存在 event-rings 目录:

```bash theme={null}
sudo mkdir -p /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings
sudo chown monad:monad /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings
```

## 配置 `systemd` 覆盖

### 重要事项

`systemd`:

* 提醒:如果您通过 `apt` 安装的 Monad,则 `systemd` 单元文件位于:`/usr/lib/systemd/system`
* 这意味着我们需要创建一个 `systemd` 覆盖
* 对于 ExecStart(及其他累加型设置)的 `systemd` 覆盖需要两个代码块。第一个"清除"原有值,第二个设置新值。
* 修改后您需要执行 `systemctl daemon-reload`

`events` + `WebSockets`:

* `RPC` + `WebSockets` 对启用了 `events` 的 `Execution` 有硬依赖

`WebSockets` 特定说明:

* 您需要在防火墙中开放一个端口
* 默认端口为 `8081`
* 如果您希望使用自定义端口,`RPC` 的 `--ws-port <PORT>` 参数可让您设置所选端口

### 为 `systemd` 配置 `Execution` 覆盖

此覆盖为 `Execution` 启用 `events` 子组件。

<Warning>
  如果在未为 `Execution` 启用 `events` 的情况下启动 `RPC` + `WebSockets`,则 `RPC` 会启动后随即崩溃。
</Warning>

您可以通过以下方式打开覆盖编辑器:

```bash theme={null}
sudo systemctl edit monad-execution
```

这将在 `/etc/systemd/system/monad-execution.service.d/override.conf` 处创建一个新文件。

文件内容(使用覆盖编辑器时看到的内容):

```ini theme={null}
### Anything between here and the comment below will become the contents of the drop-in file

# NOTE: BOTH ExecStarts are REQUIRED

[Service]
ExecStart=
ExecStart=/usr/local/bin/monad \
    --chain "$CHAIN" \
    --db /dev/triedb \
    --block_db /home/monad/monad-bft/ledger \
    --statesync /home/monad/monad-bft/statesync.sock \
    --exec-event-ring /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events \
    --sq_thread_cpu 1 \
    --log_level INFO

### Edits below this comment will be discarded
```

执行重新加载:

```bash theme={null}
sudo systemctl daemon-reload
```

### 重启 `Execution`

在此加入该步骤,以确保 `Execution` 在启用了 `events` 的情况下重新启动。

```bash theme={null}
sudo systemctl restart monad-execution
```

### 为 `systemd` 配置 `RPC` 覆盖

此覆盖为 `RPC` 启用 `WebSockets` 子组件。

您可以通过以下方式打开覆盖编辑器:

```bash theme={null}
sudo systemctl edit monad-rpc
```

这将在 `/etc/systemd/system/monad-rpc.service.d/override.conf` 处创建一个新文件。

文件内容:

```ini theme={null}
# NOTE: BOTH ExecStarts are REQUIRED

[Service]
ExecStart=
ExecStart=/usr/local/bin/monad-rpc \
    --ipc-path /home/monad/monad-bft/mempool.sock \
    --triedb-path /dev/triedb \
    --otel-endpoint "http://0.0.0.0:4317" \
    --allow-unprotected-txs \
    --node-config /home/monad/monad-bft/config/node.toml \
    --exec-event-path /var/lib/hugetlbfs/user/monad/pagesize-2MB/event-rings/monad-exec-events \
    --ws-enabled
```

### 重启 `RPC`

```bash theme={null}
sudo systemctl restart monad-rpc
```

### 检查连通性

检查 WebSocket 连通性是否正常工作的一种快捷方式是使用可作为 WebSocket 客户端的通用命令行工具,例如 [`websocat`](https://github.com/vi/websocat)。这是一款强大的命令行"瑞士军刀"工具,类似于 `nc` 或最初的 `socat`。它尚未被官方打包到 Debian/Ubuntu 中,但可以下载预编译二进制文件,或通过 `cargo install websocat` 安装(它是一个 Rust 程序)。

以下是以详细模式(`-v`)运行它的示例,WebSocket 服务托管在默认端口 8081 上:

```shell theme={null}
$ websocat -v ws://localhost:8081
[INFO  websocat::lints] Auto-inserting the line mode
[INFO  websocat::stdio_threaded_peer] get_stdio_peer (threaded)
[INFO  websocat::ws_client_peer] get_ws_client_peer
[INFO  websocat::net_peer] Connected to TCP 127.0.0.1:8081
[INFO  websocat::ws_client_peer] Connected to ws
[INFO  websocat::ws_peer] Received WebSocket ping
```

要进行订阅,请将 `eth_subscribe` 的订阅 JSON RPC 调用输入到终端的 stdin 并按下回车:

```json theme={null}
{ "id": 1, "jsonrpc": "2.0", "method": "eth_subscribe", "params": ["newHeads"] }
```

大约每半秒左右,您就会看到关于新区块的更新。
