自定义持久化提供器
将默认会话存储替换为你自己的远程服务、加密文件存储或用于测试的内存实现。
Convai Unity SDK 将会话数据——连接状态、会话 ID、恢复令牌以及编辑器端用户 GUID——存储在 PlayerPrefs 默认通过 PlayerPrefsKeyValueStore。如果 PlayerPrefs 如果适用于你的部署,你就不需要此页面。 当你需要云端保存、加密存储、服务器端会话管理,或用于自动化测试和 CI 的隔离存储时,请替换持久化提供程序。
SDK 写入存储的内容
convai.session.*
会话 ID 和恢复令牌
允许 SDK 在不重新启动 AI 回合的情况下恢复已断开的会话
convai.end_user_id
仅编辑器可用的设备 GUID(回退)
由 DeviceEndUserIdProvider 在 Unity 编辑器中使用,当无法获取硬件 ID 时
convai.prefs.*
用户偏好设置(例如静音状态)
在应用启动之间持久保存 SDK 级设置
替换持久化提供程序也就替换了所有这些内容的读写位置。你的实现必须处理 SDK 涉及的每一个键——下面的适配器模式可确保不会遗漏任何内容。
持久化接口
IKeyValueStore — 简单存储
namespace Convai.Domain.Abstractions
{
public interface IKeyValueStore
{
string GetString(string key, string defaultValue = null);
void SetString(string key, string value);
bool HasKey(string key);
void DeleteKey(string key);
void Save();
}
}Save() 在写入操作后被调用。对于内存存储,它是空操作;对于文件后端存储,它会刷新到磁盘。在不需要异步操作的本地存储场景中实现此接口。
IPersistenceProvider — 功能完整的存储
builder.UsePersistence() 接受 IPersistenceProvider. 如果你的实现是 IKeyValueStore,请将其包装在适配器中(参见 适配器模式 下文)。异步操作(SyncAsync, SaveVersionedAsync)如果你的后端是同步的,可以返回占位结果。
要实现哪个接口:
本地文件、加密 SQLite、内存
IKeyValueStore
云端保存、服务器端存储、多设备同步
IPersistenceProvider
现有 IKeyValueStore 并叠加云同步
两者都要——将同步/版本化操作委托给云客户端
支持类型
PersistenceResult
成功
bool
操作是否成功。
错误消息
string
错误描述,如果 成功 为 false.
时间戳
DateTime
操作完成时刻。
版本
long
操作后的版本号(用于版本化操作)。
PersistenceResult.Succeeded(version)
静态
创建一个成功结果。
PersistenceResult.Failed(error)
静态
创建一个失败结果。
ConflictResolutionStrategy
由 SaveVersionedAsync 用于在异步/云场景中解决写入冲突。
LastWriteWins
基于时间戳,最近写入的值获胜。
HighestVersionWins
版本号更高的值获胜。
LocalWins
本地数据始终覆盖远程数据。
RemoteWins
远程数据始终覆盖本地数据。
Manual
将冲突信息返回给调用方以便显式解决。
PersistenceOptions
实现示例
内存存储(测试 / CI)
适用于自动化测试和 CI 运行,在这些场景中,运行之间的持久状态会破坏结果。
加密文件存储
满足禁止明文的合规要求 PlayerPrefs 用于会话数据。
调用 Save() 在每次写入后,或定期刷新。写入会缓存在内存中——自上次 Save() 以来写入的数据会在崩溃时丢失。
适用于 IKeyValueStore 实现的适配器模式
builder.UsePersistence() 需要 IPersistenceProvider. 使用此适配器来包装任何 IKeyValueStore:
DeleteAll(string prefix) 在此适配器中返回失败结果。SDK 会在 DeleteAll 期间调用会话重置操作。如果你的部署需要完整的会话重置,请实现 DeleteAll 通过遍历存储的键并移除匹配前缀的键来实现。
注册提供器
故障排除
重启后会话未恢复
GetString 返回 null 在重新加载时用于会话键
确保 Save() 会在应用退出前同步调用。订阅 Application.quitting 。
NullReferenceException 内部的 IPersistenceProvider 实现
在存储初始化之前调用异步方法
在提供程序的构造函数中初始化后端存储,然后再 UsePersistence() 被调用。
崩溃时数据丢失
SetString 写入会缓存在内存中,并且 Save() 未被调用
调用 Save() 在每次写入后,或在定时器上刷新。
会话重置没有清除所有 SDK 数据
DeleteAll(prefix) 在适配器中返回失败结果
实现 DeleteAll 通过遍历存储的键集合并移除与前缀匹配的条目。
下一步
凭证、身份和存储运行时模块系统实现自定义模块最后更新于
这有帮助吗?