> For the complete documentation index, see [llms.txt](https://www.socketio4j.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.socketio4j.org/adapters/adapters-zh/jie-shao/store.md).

# Store（存储）

该 **存储** 接口为 socketio4j 定义了每会话的键值存储抽象。\
它允许传输、命名空间和用户代码持久化会话范围的小片元元数据，例如用户 ID、身份验证令牌、连接状态或房间成员提示——独立于实际的后端存储实现。

**关键特性**

* **会话范围存储** — 每个已连接的客户端会话存在一个存储实例
* **键值语义** — 任意对象与字符串键关联
* **与后端无关** — 实现可使用内存、Hazelcast、Redis 或其他数据存储
* **生命周期感知** — 在底层客户端断开连接时被销毁
* **类型安全的检索** — 返回值可以被转换或使用泛型类型

**工作原理**

* `设置` 在会话生命周期内将一个值与一个键关联
* `获取` 返回存储的值，或 `空` 如果不存在
* `存在` 在不加载值的情况下检查键是否存在
* `删除` 移除单个键值条目
* `销毁` 移除所有条目，使存储实例失效

**使用场景**

| 案例      | 示例                                         |
| ------- | ------------------------------------------ |
| 认证      | 存储 `"userId"`, `"tenant"`, `"tokenClaims"` |
| 重连提示    | 存储 `"rooms"` 或自定义元数据                       |
| 自定义握手参数 | 持久化来自升级/握手的用户元数据                           |
| 命名空间逻辑  | 附加仅在当前会话期间需要的状态                            |

**优点**

👍 在集群和独立模式下工作一致\
👍 将会话元数据隔离到每个连接\
👍 允许在不更改用户代码的情况下切换存储后端\
👍 支持单节点部署的轻量内存操作

**限制**

ℹ️ 不适用于大型对象或二进制存储\
ℹ️ 本身不是分布式数据模型 — 分布性取决于实现\
ℹ️ 除了会话生命周期外没有内置的 TTL 或过期机制\
ℹ️ 除非由共享存储作为后端，否则不会在会话之间共享

***

#### 后端行为

| 后端                                                | 持久性              | 可见性    | 特性        |
| ------------------------------------------------- | ---------------- | ------ | --------- |
| **内存中**                                           | 短暂，断开或 JVM 重启时清除 | 仅本地    | 最快，最适合单节点 |
| **Hazelcast / Redis(redis, valkey, dragonflydb)** | 分布式（基于后端配置）      | 跨节点可访问 | 推荐用于多节点部署 |

***

#### 生命周期保证

> **一个 Store 实例的存在与恰好一个客户端会话一致，并在会话结束时被销毁。**\
> 在调用 `destroy()`之后，不得再次访问该存储。
>
> 在客户端断开连接时自动调用。

#### 示例

```
server.addEventListener("storeDemo", String.class,
        (client, data, ackSender) -> {

    // ----- 设置 -----
    client.getStore().set("key1", data);
    log.info("SET key1 = {}", data);

    // ----- 获取 -----
    String value = client.getStore().get("key1");
    log.info("GET key1 = {}", value);

    // ----- 是否存在 -----
    boolean existsBefore = client.getStore().has("key1");
    log.info("HAS key1 (before delete) = {}", existsBefore);

    // ----- 删除 -----
    client.getStore().del("key1");
    log.info("DEL key1");

    // ----- 再次检查是否存在 -----
    boolean existsAfter = client.getStore().has("key1");
    log.info("HAS key1 (after delete) = {}", existsAfter);

});

```


---

# 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://www.socketio4j.org/adapters/adapters-zh/jie-shao/store.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.
