FBro浏览器独立缓存配置
概述
FBro浏览器支持为每个浏览器实例设置独立的缓存目录,这允许不同的浏览器实例拥有独立的缓存数据、Cookie、本地存储等。通过独立缓存配置,可以实现多账户隔离、数据隔离和更灵活的缓存管理。
核心概念
缓存隔离的重要性
- 多账户支持:不同浏览器实例可以同时登录不同账户
- 数据隔离:防止不同任务之间的数据污染
- Cookie隔离:每个实例拥有独立的Cookie存储
- 会话管理:独立的会话状态管理
🔧 两种配置层级
1. 框架级配置 - FBroSharpInitSet
全局初始化配置,整个应用程序只设置一次:
csharp
public struct FBroSharpInitSet
{
public string cache_path; // 框架缓存目录
public string user_data_path; // 框架用户数据目录
public string root_cache_path; // 框架根缓存目录
// ... 其他全局配置
}2. 实例级配置 - FBroSharpRequestContextSet
单个浏览器实例配置,每个浏览器实例可以不同:
csharp
public struct FBroSharpRequestContextSet
{
public string cache_path; // 实例缓存路径
public bool persist_session_cookies; // 是否持久化会话Cookie
public bool persist_user_preferences; // 是否持久化用户首选项
public bool ignore_certificate_errors; // 是否忽略证书错误
public string accept_language_list; // 接受语言列表
public string cookieable_schemes_list; // 可Cookie的协议列表
public int cookieable_schemes_exclude_defaults; // 是否排除默认可Cookie协议
}关键组件
- FBroSharpInitSet:框架全局初始化配置
- FBroSharpRequestContextSet:浏览器实例配置类
- FBroSharpRequestContext:请求上下文实例
- FBroSharpWindowsInfo:窗口信息配置
框架初始化配置
🔍 框架级三路径配置详解
FBro框架在应用程序启动时需要配置三个关键的缓存路径,这些路径必须遵循特定的层次关系:
csharp
static void Main()
{
FBroSharpInitSet set = new FBroSharpInitSet
{
//设置缓存目录
cache_path = Directory.GetCurrentDirectory() + "\\Cache\\CachePath\\",
//设置用户目录
user_data_path = Directory.GetCurrentDirectory() + "\\Cache\\UserPath\\",
//设置根缓存目录,必须是上面缓存目录的父目录,否则采用独立缓存可能会失效
root_cache_path = Directory.GetCurrentDirectory() + "\\Cache\\",
//启用事件消息循环
multi_threaded_message_loop = true,
//设置执行子进程
browser_subprocess_path = Directory.GetCurrentDirectory() + "\\FBroSubprocess.exe",
//本地化语言
locale = "zh-CN",
//日志模式
log_severity = FBroSharpLogSeverity.ERROR
};
//创建初始化事件
InitEvent init_event = new InitEvent();
//执行框架初始化
if (!FBroSharpInitControl.InitPro(set, init_event))
return;
// ... 应用程序主逻辑
}🏗️ 框架目录结构层次关系
当前应用程序目录/
└── Cache/ ← root_cache_path (框架根缓存目录)
├── CachePath/ ← cache_path (框架缓存目录)
│ ├── HTTP缓存文件
│ ├── 图片缓存
│ ├── JavaScript文件缓存
│ ├── CSS样式缓存
│ └── 其他临时缓存数据
└── UserPath/ ← user_data_path (框架用户数据目录)
├── Cookies (Cookie存储)
├── LocalStorage (本地存储)
├── SessionStorage (会话存储)
├── Preferences (用户首选项)
├── History (浏览历史)
├── Bookmarks (书签)
└── Extensions (扩展程序数据)⚠️ 重要:这是框架级配置,整个应用程序只需要设置一次,为所有浏览器实例提供基础缓存结构。
🎯 各目录功能详解
| 路径配置 | 功能作用 | 数据类型 | 重要性 | 清理策略 |
|---|---|---|---|---|
root_cache_path | 所有缓存数据的统一根目录 | 容器目录 | ⭐⭐⭐ | 整体管理 |
cache_path | 存储临时缓存数据 | 页面缓存、资源文件 | ⭐⭐ | 可定期清理 |
user_data_path | 存储用户持久数据 | Cookie、设置、历史 | ⭐⭐⭐ | 谨慎清理 |
1. root_cache_path - 根缓存目录
csharp
// 作为所有缓存目录的父容器
root_cache_path = Directory.GetCurrentDirectory() + "\\Cache\\";- 🏠 统一管理:作为所有缓存相关目录的父目录
- 🔒 隔离保证:必须包含下面两个子目录才能确保独立缓存功能正常
- 📁 批量操作:便于整体缓存清理和备份操作
2. cache_path - 浏览器缓存目录
csharp
// 存储可清理的临时缓存数据
cache_path = Directory.GetCurrentDirectory() + "\\Cache\\CachePath\\";- 🚀 性能优化:存储页面缓存、图片缓存、JavaScript文件等
- 🗑️ 可安全清理:这些数据可以被清理而不影响用户设置
- 📈 提升浏览体验:减少重复下载,提高页面加载速度
3. user_data_path - 用户数据目录
csharp
// 存储需要持久保存的用户数据
user_data_path = Directory.GetCurrentDirectory() + "\\Cache\\UserPath\\";- 👤 用户个性化:存储Cookie、本地存储、用户首选项等
- 💾 持久保存:这些数据通常需要长期保留
- 🔐 会话状态:包含登录状态和用户个人信息
⚠️ 关键设计原则
1. 严格的层次关系要求
csharp
// ✅ 正确的层次关系
root_cache_path = "C:\\App\\Cache\\"
cache_path = "C:\\App\\Cache\\CachePath\\" // cache_path 必须是 root_cache_path 的子目录
user_data_path = "C:\\App\\Cache\\UserPath\\" // user_data_path 必须是 root_cache_path 的子目录
// ❌ 错误的配置 - 会导致独立缓存失效
root_cache_path = "C:\\App\\Cache\\"
cache_path = "D:\\OtherDrive\\Cache\\" // 不是root_cache_path的子目录
user_data_path = "C:\\Users\\Data\\" // 不是root_cache_path的子目录2. 独立缓存的前提条件
- 每个浏览器实例必须有自己独立的三路径配置
- 不同实例的路径不能重叠或共享
- 必须确保目录的读写权限
3. 数据分离设计思想
- 临时数据 vs 持久数据:便于选择性清理
- 缓存数据 vs 用户数据:不同的备份和恢复策略
- 性能数据 vs 个人数据:不同的安全级别要求
浏览器实例配置
💡 独立缓存实例配置
在框架初始化完成后,每个浏览器实例可以配置自己的独立缓存:
csharp
/// <summary>
/// 创建独立缓存的浏览器实例配置
/// </summary>
/// <param name="instanceName">实例名称(用于区分不同浏览器实例)</param>
/// <returns>配置好的FBroSharpRequestContextSet</returns>
public static FBroSharpRequestContextSet CreateInstanceCacheConfig(string instanceName)
{
// 为每个实例创建独立的缓存目录
string baseDirectory = Directory.GetCurrentDirectory();
string instanceCachePath = Path.Combine(baseDirectory, "BrowserCaches", instanceName);
// 确保目录存在
if (!Directory.Exists(instanceCachePath))
{
Directory.CreateDirectory(instanceCachePath);
Console.WriteLine($"创建实例缓存目录: {instanceCachePath}");
}
// 浏览器实例配置(只有cache_path字段)
var contextSet = new FBroSharpRequestContextSet
{
cache_path = instanceCachePath, // 实例独立缓存路径
persist_session_cookies = true, // 持久化会话Cookie
persist_user_preferences = true, // 持久化用户首选项
ignore_certificate_errors = false, // 不忽略证书错误
accept_language_list = "zh-CN,zh,en", // 接受语言列表
cookieable_schemes_list = "", // 默认Cookie协议
cookieable_schemes_exclude_defaults = 0 // 包含默认协议
};
Console.WriteLine($"=== 实例缓存配置 [{instanceName}] ===");
Console.WriteLine($"缓存路径: {contextSet.cache_path}");
Console.WriteLine($"持久Cookie: {contextSet.persist_session_cookies}");
Console.WriteLine($"持久首选项: {contextSet.persist_user_preferences}");
Console.WriteLine("=======================================");
return contextSet;
}
/// <summary>
/// 多实例独立缓存结构示例
/// </summary>
public static void ConfigureMultipleInstances()
{
// 为不同账户创建独立缓存配置
var userAConfig = CreateInstanceCacheConfig("UserA");
var userBConfig = CreateInstanceCacheConfig("UserB");
var userCConfig = CreateInstanceCacheConfig("UserC");
// 结果目录结构:
// BrowserCaches/
// ├── UserA/ ← UserA的独立缓存
// ├── UserB/ ← UserB的独立缓存
// └── UserC/ ← UserC的独立缓存
}🏗️ 完整的缓存架构
应用程序目录/
├── Cache/ ← 框架级缓存 (FBroSharpInitSet)
│ ├── CachePath/
│ └── UserPath/
└── BrowserCaches/ ← 实例级缓存 (FBroSharpRequestContextSet)
├── UserA/ ← 浏览器实例A的独立缓存
├── UserB/ ← 浏览器实例B的独立缓存
├── UserC/ ← 浏览器实例C的独立缓存
└── TempTask/ ← 临时任务的独立缓存🔧 路径验证工具
csharp
/// <summary>
/// 验证缓存路径配置是否正确
/// </summary>
/// <param name="contextSet">缓存配置</param>
/// <returns>验证结果</returns>
public static CachePathValidationResult ValidateCachePaths(FBroSharpRequestContextSet contextSet)
{
var result = new CachePathValidationResult();
// 检查路径是否为空
if (string.IsNullOrEmpty(contextSet.root_cache_path))
result.AddError("root_cache_path 不能为空");
if (string.IsNullOrEmpty(contextSet.cache_path))
result.AddError("cache_path 不能为空");
if (string.IsNullOrEmpty(contextSet.user_data_path))
result.AddError("user_data_path 不能为空");
if (result.HasErrors) return result;
// 标准化路径(处理路径分隔符)
string rootPath = Path.GetFullPath(contextSet.root_cache_path.TrimEnd('\\'));
string cachePath = Path.GetFullPath(contextSet.cache_path.TrimEnd('\\'));
string userPath = Path.GetFullPath(contextSet.user_data_path.TrimEnd('\\'));
// 验证层次关系
if (!cachePath.StartsWith(rootPath + "\\"))
{
result.AddError($"cache_path 必须是 root_cache_path 的子目录\n Root: {rootPath}\n Cache: {cachePath}");
}
if (!userPath.StartsWith(rootPath + "\\"))
{
result.AddError($"user_data_path 必须是 root_cache_path 的子目录\n Root: {rootPath}\n User: {userPath}");
}
// 检查路径冲突
if (cachePath.Equals(userPath, StringComparison.OrdinalIgnoreCase))
{
result.AddError("cache_path 和 user_data_path 不能指向同一个目录");
}
// 检查路径长度(Windows限制)
if (cachePath.Length > 240) result.AddWarning("cache_path 路径过长,可能在某些系统上出现问题");
if (userPath.Length > 240) result.AddWarning("user_data_path 路径过长,可能在某些系统上出现问题");
// 权限检查
try
{
Directory.CreateDirectory(rootPath);
result.AddInfo($"根目录创建/验证成功: {rootPath}");
}
catch (Exception ex)
{
result.AddError($"无法创建根目录: {ex.Message}");
}
return result;
}
public class CachePathValidationResult
{
public List<string> Errors { get; } = new List<string>();
public List<string> Warnings { get; } = new List<string>();
public List<string> Info { get; } = new List<string>();
public bool IsValid => Errors.Count == 0;
public bool HasErrors => Errors.Count > 0;
public bool HasWarnings => Warnings.Count > 0;
public void AddError(string error) => Errors.Add(error);
public void AddWarning(string warning) => Warnings.Add(warning);
public void AddInfo(string info) => Info.Add(info);
public void PrintResults()
{
if (HasErrors)
{
Console.WriteLine("❌ 配置错误:");
Errors.ForEach(e => Console.WriteLine($" • {e}"));
}
if (HasWarnings)
{
Console.WriteLine("⚠️ 配置警告:");
Warnings.ForEach(w => Console.WriteLine($" • {w}"));
}
if (Info.Count > 0)
{
Console.WriteLine("ℹ️ 配置信息:");
Info.ForEach(i => Console.WriteLine($" • {i}"));
}
Console.WriteLine($"✅ 配置验证结果: {(IsValid ? "通过" : "失败")}");
}
}
## 基础配置
### 1. 简单独立缓存配置
```csharp
/// <summary>
/// 创建具有独立缓存的浏览器实例
/// </summary>
/// <param name="url">初始URL</param>
/// <param name="cacheName">缓存目录名称</param>
/// <param name="parentHandle">父窗口句柄</param>
/// <param name="width">浏览器宽度</param>
/// <param name="height">浏览器高度</param>
/// <returns>浏览器实例</returns>
public IFBroSharpBrowser CreateBrowserWithCache(string url, string cacheName, IntPtr parentHandle, int width, int height)
{
try
{
// 创建浏览器事件处理器
var browserEvent = new BrowserEvent();
// 配置窗口信息
var windowInfo = new FBroSharpWindowsInfo
{
parent_window = parentHandle,
width = width,
height = height,
x = 0,
y = 0
};
// 使用标准三路径配置创建独立缓存
var contextSet = CreateStandardCacheConfig(cacheName);
// 创建请求上下文
var requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
Console.WriteLine($"缓存目录: {requestContext.GetCachePath()}");
// 创建浏览器实例
var browser = FBroSharpControl.CreatBrowser(url, windowInfo, default, requestContext, default, browserEvent, default);
Console.WriteLine($"浏览器创建成功,缓存目录: {cacheName}");
return browser;
}
catch (Exception ex)
{
Console.WriteLine($"创建独立缓存浏览器失败: {ex.Message}");
throw;
}
}2. 高级缓存配置
csharp
/// <summary>
/// 创建具有完整配置的独立缓存浏览器
/// </summary>
/// <param name="config">浏览器配置</param>
/// <returns>浏览器实例</returns>
public IFBroSharpBrowser CreateAdvancedCacheBrowser(BrowserCacheConfig config)
{
try
{
var browserEvent = new BrowserEvent();
// 配置窗口信息
var windowInfo = new FBroSharpWindowsInfo
{
parent_window = config.ParentHandle,
width = config.Width,
height = config.Height,
x = config.X,
y = config.Y
};
// 使用标准三路径配置,支持完整的缓存结构
var contextSet = CreateStandardCacheConfig(config.CacheName);
// 验证配置是否正确
var validationResult = ValidateCachePaths(contextSet);
if (!validationResult.IsValid)
{
validationResult.PrintResults();
throw new ArgumentException("缓存路径配置验证失败");
}
// 创建请求上下文
var requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
// 记录配置信息
LogCacheConfiguration(config.CacheName, requestContext);
// 创建浏览器
var browser = FBroSharpControl.CreatBrowser(
config.InitialUrl,
windowInfo,
default,
requestContext,
default,
browserEvent,
default
);
return browser;
}
catch (Exception ex)
{
Console.WriteLine($"创建高级缓存浏览器失败: {ex.Message}");
throw;
}
}
/// <summary>
/// 创建缓存目录
/// </summary>
/// <param name="cacheName">缓存名称</param>
/// <returns>完整缓存路径</returns>
private string CreateCacheDirectory(string cacheName)
{
string basePath = Directory.GetCurrentDirectory();
string fullCachePath = Path.Combine(basePath, "Cache", cacheName);
// 确保目录存在
if (!Directory.Exists(fullCachePath))
{
Directory.CreateDirectory(fullCachePath);
Console.WriteLine($"创建缓存目录: {fullCachePath}");
}
else
{
Console.WriteLine($"使用现有缓存目录: {fullCachePath}");
}
return fullCachePath;
}
/// <summary>
/// 记录缓存配置信息
/// </summary>
/// <param name="cacheName">缓存名称</param>
/// <param name="requestContext">请求上下文</param>
private void LogCacheConfiguration(string cacheName, FBroSharpRequestContext requestContext)
{
Console.WriteLine("=== 缓存配置信息 ===");
Console.WriteLine($"缓存名称: {cacheName}");
Console.WriteLine($"缓存路径: {requestContext.GetCachePath()}");
Console.WriteLine($"配置时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine("===================");
}配置类定义
BrowserCacheConfig 配置类
csharp
/// <summary>
/// 浏览器缓存配置类
/// </summary>
public class BrowserCacheConfig
{
/// <summary>
/// 缓存目录名称
/// </summary>
public string CacheName { get; set; }
/// <summary>
/// 初始URL
/// </summary>
public string InitialUrl { get; set; } = "about:blank";
/// <summary>
/// 父窗口句柄
/// </summary>
public IntPtr ParentHandle { get; set; } = IntPtr.Zero;
/// <summary>
/// 浏览器宽度
/// </summary>
public int Width { get; set; } = 1024;
/// <summary>
/// 浏览器高度
/// </summary>
public int Height { get; set; } = 768;
/// <summary>
/// X坐标位置
/// </summary>
public int X { get; set; } = 0;
/// <summary>
/// Y坐标位置
/// </summary>
public int Y { get; set; } = 0;
/// <summary>
/// 是否自动创建目录
/// </summary>
public bool AutoCreateDirectory { get; set; } = true;
/// <summary>
/// 自定义缓存根目录
/// </summary>
public string CustomCacheRoot { get; set; } = null;
/// <summary>
/// 获取完整缓存路径
/// </summary>
/// <returns>完整缓存路径</returns>
public string GetFullCachePath()
{
string baseDirectory = CustomCacheRoot ?? Directory.GetCurrentDirectory();
return Path.Combine(baseDirectory, "Cache", CacheName);
}
}缓存管理器
CacheManager 管理类
csharp
/// <summary>
/// 缓存管理器
/// </summary>
public class CacheManager
{
private readonly Dictionary<string, IFBroSharpBrowser> _browsers = new Dictionary<string, IFBroSharpBrowser>();
private readonly Dictionary<string, string> _cachePaths = new Dictionary<string, string>();
/// <summary>
/// 创建具有独立缓存的浏览器
/// </summary>
/// <param name="browserId">浏览器ID</param>
/// <param name="config">配置信息</param>
/// <returns>浏览器实例</returns>
public IFBroSharpBrowser CreateCachedBrowser(string browserId, BrowserCacheConfig config)
{
if (_browsers.ContainsKey(browserId))
{
Console.WriteLine($"浏览器 {browserId} 已存在,返回现有实例");
return _browsers[browserId];
}
try
{
// 设置缓存名称为浏览器ID(如果未指定)
if (string.IsNullOrEmpty(config.CacheName))
{
config.CacheName = browserId;
}
var browser = CreateAdvancedCacheBrowser(config);
// 存储浏览器实例和缓存路径
_browsers[browserId] = browser;
_cachePaths[browserId] = config.GetFullCachePath();
Console.WriteLine($"浏览器 {browserId} 创建成功");
return browser;
}
catch (Exception ex)
{
Console.WriteLine($"创建浏览器 {browserId} 失败: {ex.Message}");
throw;
}
}
/// <summary>
/// 获取浏览器实例
/// </summary>
/// <param name="browserId">浏览器ID</param>
/// <returns>浏览器实例</returns>
public IFBroSharpBrowser GetBrowser(string browserId)
{
return _browsers.TryGetValue(browserId, out var browser) ? browser : null;
}
/// <summary>
/// 获取缓存路径
/// </summary>
/// <param name="browserId">浏览器ID</param>
/// <returns>缓存路径</returns>
public string GetCachePath(string browserId)
{
return _cachePaths.TryGetValue(browserId, out var path) ? path : null;
}
/// <summary>
/// 清理指定浏览器的缓存
/// </summary>
/// <param name="browserId">浏览器ID</param>
/// <returns>是否成功</returns>
public bool ClearCache(string browserId)
{
try
{
if (_cachePaths.TryGetValue(browserId, out var cachePath))
{
if (Directory.Exists(cachePath))
{
Directory.Delete(cachePath, true);
Console.WriteLine($"缓存清理成功: {cachePath}");
return true;
}
}
Console.WriteLine($"缓存路径不存在: {browserId}");
return false;
}
catch (Exception ex)
{
Console.WriteLine($"清理缓存失败: {ex.Message}");
return false;
}
}
/// <summary>
/// 关闭并清理浏览器
/// </summary>
/// <param name="browserId">浏览器ID</param>
/// <param name="clearCache">是否清理缓存</param>
public void CloseBrowser(string browserId, bool clearCache = false)
{
if (_browsers.TryGetValue(browserId, out var browser))
{
browser?.Dispose();
_browsers.Remove(browserId);
if (clearCache)
{
ClearCache(browserId);
}
_cachePaths.Remove(browserId);
Console.WriteLine($"浏览器 {browserId} 已关闭");
}
}
/// <summary>
/// 获取所有浏览器信息
/// </summary>
/// <returns>浏览器信息列表</returns>
public List<BrowserInfo> GetAllBrowsers()
{
var browserInfos = new List<BrowserInfo>();
foreach (var kvp in _browsers)
{
var info = new BrowserInfo
{
BrowserId = kvp.Key,
CachePath = _cachePaths.GetValueOrDefault(kvp.Key),
IsValid = kvp.Value != null
};
browserInfos.Add(info);
}
return browserInfos;
}
private IFBroSharpBrowser CreateAdvancedCacheBrowser(BrowserCacheConfig config)
{
// 这里复用前面定义的方法
var browserEvent = new BrowserEvent();
var windowInfo = new FBroSharpWindowsInfo
{
parent_window = config.ParentHandle,
width = config.Width,
height = config.Height,
x = config.X,
y = config.Y
};
// 使用标准三路径配置
var contextSet = CreateStandardCacheConfig(config.CacheName);
// 如果指定了自定义根目录,需要重新配置路径
if (!string.IsNullOrEmpty(config.CustomCacheRoot))
{
string instanceCacheRoot = Path.Combine(config.CustomCacheRoot, "Cache", config.CacheName);
contextSet = new FBroSharpRequestContextSet
{
root_cache_path = instanceCacheRoot + "\\",
cache_path = Path.Combine(instanceCacheRoot, "CachePath") + "\\",
user_data_path = Path.Combine(instanceCacheRoot, "UserPath") + "\\"
};
// 确保自定义路径目录存在
if (config.AutoCreateDirectory)
{
Directory.CreateDirectory(contextSet.root_cache_path);
Directory.CreateDirectory(contextSet.cache_path);
Directory.CreateDirectory(contextSet.user_data_path);
}
}
var requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
return FBroSharpControl.CreatBrowser(
config.InitialUrl,
windowInfo,
default,
requestContext,
default,
browserEvent,
default
);
}
}
/// <summary>
/// 浏览器信息类
/// </summary>
public class BrowserInfo
{
public string BrowserId { get; set; }
public string CachePath { get; set; }
public bool IsValid { get; set; }
public DateTime CreatedTime { get; set; } = DateTime.Now;
}实际应用示例
🎯 创建独立缓存浏览器实例
csharp
// 1. 首先确保框架已初始化(在应用程序启动时完成)
static void Main()
{
// ... 前面的框架初始化代码 ...
// 2. 为不同任务创建独立缓存的浏览器实例
CreateMultipleBrowserInstances();
}
static void CreateMultipleBrowserInstances()
{
// 创建用户A的浏览器实例(独立缓存)
CreateBrowserWithCache("UserA", "https://www.google.com");
// 创建用户B的浏览器实例(独立缓存)
CreateBrowserWithCache("UserB", "https://www.bing.com");
// 创建临时任务的浏览器实例(独立缓存)
CreateBrowserWithCache("TempTask", "https://www.example.com");
}
static void CreateBrowserWithCache(string instanceName, string url)
{
// 1. 创建实例级缓存配置
FBroSharpRequestContextSet contextSet = CreateInstanceCacheConfig(instanceName);
// 2. 创建请求上下文
FBroSharpRequestContext context = FBroSharpRequestContext.CreateContext(contextSet);
// 3. 窗口配置
FBroSharpWindowsInfo windowsInfo = new FBroSharpWindowsInfo
{
url = url,
width = 1024,
height = 768,
x = 100,
y = 100
};
// 4. 创建具有独立缓存的浏览器窗口
FBroSharpWindows browser = FBroSharpWindows.CreateBrowser(windowsInfo, context);
Console.WriteLine($"创建浏览器实例 [{instanceName}] - URL: {url}");
}1. 多账户浏览器管理
csharp
public class MultiAccountBrowserManager
{
private readonly Dictionary<string, FBroSharpWindows> _browsers = new Dictionary<string, FBroSharpWindows>();
/// <summary>
/// 为不同账户创建独立浏览器
/// </summary>
/// <param name="accounts">账户列表</param>
/// <returns>创建的浏览器数量</returns>
public int CreateAccountBrowsers(List<string> accounts)
{
int successCount = 0;
foreach (string account in accounts)
{
try
{
// 创建实例级独立缓存配置
var contextSet = CreateInstanceCacheConfig($"account_{account}");
var context = FBroSharpRequestContext.CreateContext(contextSet);
// 窗口配置
var windowInfo = new FBroSharpWindowsInfo
{
url = "https://example.com/login",
width = 1200,
height = 800,
x = successCount * 50, // 错开窗口位置
y = successCount * 50
};
// 创建浏览器实例
var browser = FBroSharpWindows.CreateBrowser(windowInfo, context);
_browsers[account] = browser;
successCount++;
Console.WriteLine($"账户 {account} 的浏览器创建成功");
}
catch (Exception ex)
{
Console.WriteLine($"账户 {account} 的浏览器创建失败: {ex.Message}");
}
}
Console.WriteLine($"成功创建 {successCount}/{accounts.Count} 个账户浏览器");
return successCount;
}
/// <summary>
/// 获取账户浏览器
/// </summary>
/// <param name="account">账户名</param>
/// <returns>浏览器实例</returns>
public FBroSharpWindows GetAccountBrowser(string account)
{
return _browsers.ContainsKey(account) ? _browsers[account] : null;
}
/// <summary>
/// 切换到指定账户浏览器
/// </summary>
/// <param name="account">账户名</param>
/// <param name="url">要访问的URL</param>
/// <returns>是否成功</returns>
public bool SwitchToAccount(string account, string url = null)
{
var browser = GetAccountBrowser(account);
if (browser != null)
{
if (!string.IsNullOrEmpty(url))
{
browser.LoadUrl(url);
}
// 激活窗口
browser.ShowWindow();
Console.WriteLine($"已切换到账户: {account}");
return true;
}
Console.WriteLine($"账户 {account} 的浏览器不存在");
return false;
}
/// <summary>
/// 关闭账户浏览器
/// </summary>
/// <param name="account">账户名</param>
/// <returns>是否成功</returns>
public bool CloseAccountBrowser(string account)
{
if (_browsers.ContainsKey(account))
{
var browser = _browsers[account];
browser.CloseBrowser();
_browsers.Remove(account);
Console.WriteLine($"已关闭账户 {account} 的浏览器");
return true;
}
Console.WriteLine($"账户 {account} 的浏览器不存在");
return false;
}
/// <summary>
/// 关闭所有账户浏览器
/// </summary>
public void CloseAllAccountBrowsers()
{
foreach (var kvp in _browsers)
{
kvp.Value.CloseBrowser();
Console.WriteLine($"已关闭账户 {kvp.Key} 的浏览器");
}
_browsers.Clear();
Console.WriteLine($"已关闭所有账户浏览器");
}
}2. 任务隔离浏览器创建
csharp
public class TaskIsolatedBrowserFactory
{
private readonly Dictionary<string, FBroSharpWindows> _taskBrowsers = new Dictionary<string, FBroSharpWindows>();
/// <summary>
/// 为特定任务创建隔离浏览器
/// </summary>
/// <param name="taskId">任务ID</param>
/// <param name="taskType">任务类型</param>
/// <returns>浏览器实例</returns>
public FBroSharpWindows CreateTaskBrowser(string taskId, string taskType)
{
try
{
// 创建任务专用缓存配置
string cacheName = $"task_{taskType}_{taskId}_{DateTime.Now:yyyyMMdd_HHmmss}";
var contextSet = CreateInstanceCacheConfig(cacheName);
var context = FBroSharpRequestContext.CreateContext(contextSet);
// 窗口配置
var windowInfo = new FBroSharpWindowsInfo
{
url = "about:blank",
width = 1024,
height = 768
};
// 创建浏览器实例
var browser = FBroSharpWindows.CreateBrowser(windowInfo, context);
_taskBrowsers[taskId] = browser;
Console.WriteLine($"任务浏览器创建成功: {taskId} ({taskType})");
return browser;
}
catch (Exception ex)
{
Console.WriteLine($"任务浏览器创建失败: {taskId} - {ex.Message}");
throw;
}
}
/// <summary>
/// 批量创建任务浏览器
/// </summary>
/// <param name="tasks">任务列表</param>
/// <returns>浏览器实例字典</returns>
public Dictionary<string, FBroSharpWindows> CreateBatchTaskBrowsers(List<(string taskId, string taskType)> tasks)
{
var browsers = new Dictionary<string, FBroSharpWindows>();
foreach (var (taskId, taskType) in tasks)
{
try
{
var browser = CreateTaskBrowser(taskId, taskType);
browsers[taskId] = browser;
}
catch (Exception ex)
{
Console.WriteLine($"任务浏览器创建失败: {taskId} - {ex.Message}");
}
}
Console.WriteLine($"成功创建 {browsers.Count}/{tasks.Count} 个任务浏览器");
return browsers;
}
/// <summary>
/// 获取任务浏览器
/// </summary>
/// <param name="taskId">任务ID</param>
/// <returns>浏览器实例</returns>
public FBroSharpWindows GetTaskBrowser(string taskId)
{
return _taskBrowsers.ContainsKey(taskId) ? _taskBrowsers[taskId] : null;
}
/// <summary>
/// 关闭任务浏览器
/// </summary>
/// <param name="taskId">任务ID</param>
/// <returns>是否成功</returns>
public bool CloseTaskBrowser(string taskId)
{
if (_taskBrowsers.ContainsKey(taskId))
{
var browser = _taskBrowsers[taskId];
browser.CloseBrowser();
_taskBrowsers.Remove(taskId);
Console.WriteLine($"已关闭任务 {taskId} 的浏览器");
return true;
}
Console.WriteLine($"任务 {taskId} 的浏览器不存在");
return false;
}
}最佳实践
1. 缓存目录命名规范
csharp
public static class CacheNamingConvention
{
/// <summary>
/// 生成账户缓存名称
/// </summary>
/// <param name="account">账户名</param>
/// <returns>缓存目录名</returns>
public static string ForAccount(string account)
{
return $"account_{SanitizeName(account)}";
}
/// <summary>
/// 生成任务缓存名称
/// </summary>
/// <param name="taskType">任务类型</param>
/// <param name="taskId">任务ID</param>
/// <returns>缓存目录名</returns>
public static string ForTask(string taskType, string taskId)
{
return $"task_{SanitizeName(taskType)}_{SanitizeName(taskId)}_{DateTime.Now:yyyyMMdd_HHmmss}";
}
/// <summary>
/// 生成临时缓存名称
/// </summary>
/// <returns>缓存目录名</returns>
public static string ForTemporary()
{
return $"temp_{Guid.NewGuid():N}";
}
/// <summary>
/// 清理文件名中的非法字符
/// </summary>
/// <param name="name">原始名称</param>
/// <returns>清理后的名称</returns>
private static string SanitizeName(string name)
{
if (string.IsNullOrEmpty(name))
return "unknown";
// 移除或替换非法字符
char[] invalidChars = Path.GetInvalidFileNameChars();
foreach (char c in invalidChars)
{
name = name.Replace(c, '_');
}
// 限制长度
if (name.Length > 50)
name = name.Substring(0, 50);
return name;
}
}2. 缓存管理建议
✅ 推荐做法
- 明确分层:区分框架级配置和实例级配置
- 合理命名:使用有意义的缓存目录名称
- 适时清理:及时关闭不需要的浏览器实例
- 错误处理:妥善处理缓存创建失败的情况
❌ 避免做法
- 混淆配置:不要混淆FBroSharpInitSet和FBroSharpRequestContextSet
- 路径冲突:避免多个实例使用相同的缓存路径
- 资源泄漏:未关闭的浏览器实例会占用系统资源
- 路径过长:避免缓存路径过长导致的系统问题
3. 完整使用流程
csharp
// 1. 应用程序启动时 - 框架初始化(一次性)
static void Main()
{
// 框架级配置
FBroSharpInitSet initSet = new FBroSharpInitSet
{
cache_path = Directory.GetCurrentDirectory() + "\\Cache\\CachePath\\",
user_data_path = Directory.GetCurrentDirectory() + "\\Cache\\UserPath\\",
root_cache_path = Directory.GetCurrentDirectory() + "\\Cache\\",
multi_threaded_message_loop = true,
browser_subprocess_path = Directory.GetCurrentDirectory() + "\\FBroSubprocess.exe",
locale = "zh-CN"
};
InitEvent initEvent = new InitEvent();
if (!FBroSharpInitControl.InitPro(initSet, initEvent))
{
Console.WriteLine("框架初始化失败");
return;
}
// 2. 创建独立缓存的浏览器实例
CreateIndependentBrowsers();
}
static void CreateIndependentBrowsers()
{
// 为不同场景创建独立缓存浏览器
var userA = CreateBrowserInstance("UserA");
var userB = CreateBrowserInstance("UserB");
var tempTask = CreateBrowserInstance("TempTask");
// ... 使用浏览器实例 ...
// 3. 清理资源
userA?.CloseBrowser();
userB?.CloseBrowser();
tempTask?.CloseBrowser();
}
static FBroSharpWindows CreateBrowserInstance(string instanceName)
{
// 实例级配置
var contextSet = new FBroSharpRequestContextSet
{
cache_path = Path.Combine(Directory.GetCurrentDirectory(), "BrowserCaches", instanceName),
persist_session_cookies = true,
persist_user_preferences = true
};
var context = FBroSharpRequestContext.CreateContext(contextSet);
var windowInfo = new FBroSharpWindowsInfo
{
url = "about:blank",
width = 1024,
height = 768
};
return FBroSharpWindows.CreateBrowser(windowInfo, context);
}常见问题
Q1: 如何判断缓存是否独立成功?
A: 检查不同浏览器实例是否可以同时登录不同账户,如果可以则说明缓存已成功隔离。
Q2: 缓存目录会自动创建吗?
A: 是的,FBro会自动创建指定的缓存目录。
Q3: 可以动态修改缓存路径吗?
A: 不可以,缓存路径在浏览器实例创建时确定,无法动态修改。
Q4: 多个实例可以共享同一个缓存目录吗?
A: 不建议,这会导致缓存冲突,失去独立缓存的意义。
Q5: 如何清理缓存?
A: 关闭浏览器实例后,可以直接删除对应的缓存目录。
总结
通过正确区分框架级配置和实例级配置,你可以:
- 🔧 框架初始化:使用
FBroSharpInitSet进行一次性全局配置 - 🎯 实例创建:使用
FBroSharpRequestContextSet为每个浏览器实例配置独立缓存 - 🏗️ 架构清晰:框架缓存为基础,实例缓存实现隔离
- ✅ 最佳实践:合理命名、及时清理、错误处理
独立缓存功能让你可以轻松实现多账户管理、任务隔离等高级应用场景。
📚 相关文档:
- 异步执行JS获取元素坐标 - 异步JavaScript执行高级应用
- 其他FBro功能文档