查看器工作原理

文档请求生命周期

Doconut 将文档渲染为分页图像,由你的 Web.config 注册的 HTTP 处理程序提供服务。了解生命周期——打开、令牌、页面请求、关闭——可以解释几乎所有你会观察到的行为,包括错误信息。

关键组成部分

  • Viewer — 你从 DoconutHost.Services 解析的公共服务。它打开文档并返回会话令牌。
  • 文档会话 — 一个在服务器端保存已加载文档的对象,按其令牌保存在内存中。
  • DocImage.axd — 在 Web.config 中声明的 Doconut.DocImageHandler。它响应浏览器小部件发出的每个请求(页面、缩略图、搜索、注释,…),始终通过令牌识别。
  • /doconut-res/* — Doconut.DoconutResourceModule,为小部件提供自身的脚本、样式和图标。

Viewer 是无状态的 —— 设计如此

Viewer 不保存每个请求的文档状态,也不实现 IDisposable。会话独立于它存在,并通过过期或显式的 CloseDocument(token) 进行清理。System.Web 没有构造函数注入,因此在需要的地方解析它——通常在控制器操作中:

csharp
// POST /ViewerApi/Open?fileName=Sample.pdf
[HttpPost]
public async Task<ActionResult> Open(string fileName)
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
    var path   = Server.MapPath("~/files/" + Path.GetFileName(fileName));

    var token = await viewer.OpenDocumentAsync(path);
    return Content(token, "text/plain");
}

OpenDocumentAsync 内部发生了什么

  1. 许可证检查。 被拒绝的许可证(被篡改、列入黑名单,或在许可证更新窗口之外的构建)会立即抛出 LicenseException,并将原因作为消息。对于无效许可证,打开操作永不静默降级;缺失许可证仅会添加水印。
  2. 会话创建。 查看器工厂根据文件扩展名选择相应的格式查看器并加载文档(参见Rendering Pipeline)。会话以新的随机令牌存储在内存中,具有 滑动过期 时间,DocOptions.TimeOut 分钟(默认 60)。每次页面请求都会重置计时。
  3. 访问授权。 使用 UnsafeMode = false(默认),令牌绑定到打开它的请求的 ASP.NET 会话:在该会话中写入一个 secure-{token} 条目。因此打开操作必须在具有会话状态的请求中运行——参见Sessions & Security。
  4. 令牌被返回。 这是浏览器后续所有操作唯一需要的标识符。

异步重载可以接受文件路径、带有每种格式配置的文件路径(PdfConfig、WordConfig,…),或一个 Stream 加上一个根据扩展名选择格式的 FileInfo。对于不使用异步页面的 Web Forms 代码隐藏,OpenDocument 同步提供相同的三种输入(路径、带文件名的流,或带文件名的字节数组)。

小部件如何获取页面

小部件使用查询字符串中的令牌调用 DocImage.axd。处理程序的行为取决于请求:

查询目的
?token=…&page=N渲染的页面图像(PNG)
?token=…&page=N&thumb=1缩略图
?token=…&zoom=…放大页面渲染
?token=…&search=term全文搜索(受许可证限制)
?token=…&bookmarks文档大纲和书签
?token=…&copy / &showlinks / &fileFormat / &meta文本复制、超链接、格式信息、DICOM 元数据
?token=…&action=rotate/flip/close页面操作和显式关闭(POST)
?token=…&AnnSave=… / &AnnLoad保存和加载注释

每个请求首先进行检查:

  • 无令牌 → 404,或在 ShowDoconutInfo = true 时显示版本横幅。
  • 令牌未授予此 ASP.NET 会话 → 显示读取 You Are Not Authorized To View This Page. 的错误图片
  • 未知或已过期的令牌 → 显示读取 Document session not found. Please re-open document. 的错误图片

错误图片是普通的 PNG,使用 200 状态码发送,这样小部件可以在页面位置显示它们。仅检查状态码的监控会把它们报告为已提供的页面;真实页面大小为数十到数百千字节,而错误图片约为 2 KB。

关闭文档

csharp
viewer.CloseDocument(token);

CloseDocument 删除会话(立即释放文档引擎及其内存),从当前请求的 ASP.NET 会话中移除 secure-{token} 条目,并撤销令牌。这是可选的——滑动过期会进行相同的清理——但对于大文档,它能在用户完成时立即释放内存。从浏览器端,objViewer.Close(true) 向 DocImage.axd 发送等效的关闭请求。

要点

  • 一个打开的文档 = 一个会话 = 一个令牌,授予打开它的 ASP.NET 会话。
  • 令牌在滑动窗口内过期;如果查看器在超过 DocOptions.TimeOut 后保持空闲,需要重新打开。
  • Viewer 可以自由解析并共享;会话携带所有状态。

此页面对您有帮助吗?