Viewer の動作

ドキュメントリクエストのライフサイクル

Doconut はドキュメントをページ化された画像として、ASP.NET Core ミドルウェアを通じて配信します。ライフサイクル(オープン、トークン、ページリクエスト、クローズ)を理解すれば、エラーメッセージを含むほぼすべての挙動を説明できます。

三つの主要コンポーネント

  • Viewer — 注入する公開サービスです。ドキュメントを開き、セッショントークンを返します。
  • ドキュメントセッション — ロードされたドキュメントを保持するサーバー側オブジェクトで、IMemoryCache のトークンをキーにしています。
  • Doconut ミドルウェア — UseDoconut() によって追加され、ブラウザウィジェットが行うすべてのリクエスト(pages、thumbnails、search、annotations、…)に応答します。常にトークンで認証されます。

Viewer はステートレスです — 設計上

Viewer はシールドされており、リクエストごとのドキュメント状態を保持せず、意図的に IDisposable を実装しません。セッションはセッションマネージャーで独立して管理され、キャッシュの期限切れまたは明示的な CloseDocument(token) によってクリーンアップされます。

もはや自分で構築する必要はありません。AddDoconut() はそれをトランジェントサービスとして登録します。必要な場所へ注入してください:

csharp
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync($"files/{fileName}");
    return Results.Content(token, "text/plain");
});

MVC アプリケーションではコンストラクタパラメータとして取得し、Razor ビューでは使用します @inject Doconut.Viewer Viewer. Viewer インスタンスのアプリケーション所有キャッシュは 必要が なくなりました — そして正しくもありません。キャッシュすべきものを保持していないためです。

OpenDocumentAsync の内部で何が起こるか

  1. ライセンスゲート。 拒否された、またはバージョン期限切れのライセンス(ブラックリスト登録、改ざん、またはライセンス更新ウィンドウ外のビルド)は、即座に LicenseException をスローし、拒否理由をメッセージとして提供します — 無効な(欠如しているのとは対照的に)ライセンスに対しては、オープンは決して黙って劣化しません。カレンダー期限切れの一時的またはサブスクリプションライセンスは例外で、スローせずにウォーターマークに劣化します。
  2. セッション作成。 ビューワーファクトリはファイル拡張子に適したフォーマットビューワーを選択し、ドキュメントをロードします(Rendering Pipeline 参照)。セッションは新しい GUID トークンで IMemoryCache に保存され、スライディング有効期限 — DocOptions.TimeOut 分(デフォルト 60)を持ちます。各ページリクエストで時計がリセットされます。
  3. セキュリティ登録。 UnsafeMode = false(デフォルト)を使用すると、トークンは呼び出し元の ASP.NET セッションにバインドされます。secure-{token} マーカーがセッションに書き込まれ、ドキュメントを開いたブラウザセッションだけがページをリクエストできるようになります。
  4. トークンが返されます。 それは以降のすべての操作に対する唯一の認証情報です。

別個のウォームアップステップはありません。以前のライブラリはその目的で InitCache() を提供していましたが、現在は存在せず、代替もありません。

3 つのオーバーロードは入力のみが異なります:ファイルパス、ファイルパスにフォーマット別設定(PdfConfig、WordConfig、…)を加えたもの、または拡張子でフォーマット検出を行う Stream と FileInfo の組み合わせです。

ウィジェットがページを取得する方法

クライアントウィジェットはクエリ文字列にトークンを付けて Doconut ミドルウェアを呼び出します。ミドルウェアの動作はリクエストに依存します:

クエリ目的
?token=…&page=Nレンダリングされたページ画像(PNG)
?token=…&page=N&thumb=1サムネイル
?token=…&zoom=…拡大ページのレンダリング
?token=…&search=term全文検索(ライセンス制御)
?token=…&bookmarksドキュメントアウトライン/ブックマーク
?token=…&copy / &showlinks / &fileFormatテキストコピー、ハイパーリンク、フォーマット情報
?token=…&metaDICOM 技術メタデータ;このパッケージの DICOM セッションに対して 501 を返します
?token=…&action=rotate/flip/closeページアクションと明示的なクローズ
?token=…&AnnSave=… / &AnnLoad注釈の保存/読み込み

これらのパスはすべて最初に検証されます:

  • トークンなし → ミドルウェアは 404 を返します(ShowDoconutInfo = true の場合はバージョンバナーを返すこともあります)。
  • 不明または期限切れのトークン → Document session not found. Please re-open document. を含むエラー画像が返されます。
  • セッションミドルウェアが欠如(UnsafeMode = false 使用時) → Session middleware not configured. Call UseSession() before UseDoconut(). を伴う HTTP 500 が返されます。
  • 別のブラウザセッションでトークンが開かれた → You Are Not Authorized To View This Page. を含むエラー画像が返されます。

ミドルウェアのマウント場所

UseDoconut() はトークンを含むリクエストに応答し、マウント場所に関係なく機能します。リファレンス アプリケーションは歴史的な DocImage.axd リクエスト形状を MapWhen ブランチ上に保持しているため、
既存のクライアントは常に同じ URL を呼び出し続けます。選択に関わらず、クライアントの
BasePath がそれと一致している必要があります — ViewerConfig(ビューア設定) を参照してください。

ページを開くノードではなく共有ストレージから提供するのは、全く別の構成です
です。詳しくは 分散デプロイ を参照してください。

ドキュメントのクローズ

csharp
viewer.CloseDocument(token);

CloseDocument はキャッシュからセッションを削除し(基盤となるドキュメントエンジンを破棄し、メモリを即座に解放します)、secure-{token} マーカーを削除し、アクセス権を取り消します。呼び出しは任意です — スライディング有効期限が自動的に同じクリーンアップを行います — ただし大きなドキュメントの場合、ユーザーが終了した瞬間にメモリを解放する礼儀正しい方法です。

注入された Viewer 上で呼び出されます。以前のパターン — 短命の
Viewer を using ブロック内でトークンを閉じるだけの目的で構築する — 同等のものはなく、必要ありません。

要点

  • 1つのオープンドキュメント = 1つのセッション = 1つのトークン。トークンはブラウザセッションごとに付与され、グローバルな URL ではありません。
  • トークンはスライディングウィンドウで期限切れになります;DocOptions.TimeOut を過ぎてアイドル状態のビューアは再オープンが必要です。
  • Viewer は注入して自由に共有できます;セッションがすべての状態を保持します。

このページは役に立ちましたか?