ビューアの動作概要

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

Doconut はドキュメントをページ単位の画像としてレンダリングし、Web.config に登録された HTTP ハンドラが配信します。ライフサイクル(オープン、トークン、ページリクエスト、クローズ)を理解すれば、観測されるほぼすべての挙動やエラーメッセージが説明できます。

構成要素

  • Viewer — DoconutHost.Services から取得できる公開サービスです。ドキュメントを開き、セッショントークンを返します。
  • ドキュメントセッション — トークンに紐付けてメモリ上に保持されるサーバー側オブジェクトです。
  • DocImage.axd — Web.config で宣言された Doconut.DocImageHandler です。ブラウザウィジェットが行うすべてのリクエスト(ページ、サムネイル、検索、注釈 …)に応答し、常にトークンで識別されます。
  • /doconut-res/* — ウィジェット自身のスクリプト、スタイル、アイコンを配信する Doconut.DoconutResourceModule です。

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

Viewer はリクエストごとのドキュメント状態を保持せず、IDisposable を実装しません。セッションは Viewer とは独立して存続し、期限切れまたは明示的な 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. セッション作成。 ビューアファクトリがファイル拡張子に応じたフォーマットビューアを選択し、ドキュメントをロードします(レンダリング パイプライン を参照)。セッションは新しいランダムトークンの下にメモリ上に保存され、DocOptions.TimeOut 分(デフォルト 60 分)のスライディング有効期限が設定されます。ページリクエストがあるたびに有効期限はリセットされます。
  3. アクセス付与。 UnsafeMode = false(デフォルト)の場合、トークンはオープンしたリクエストの ASP.NET セッションに紐付けられ、secure-{token} エントリがそのセッションに書き込まれます。そのため、オープンはセッションステートを持つリクエスト内で実行する必要があります(セッションとセキュリティ を参照)。
  4. トークンが返される。 これがブラウザが以降の操作で必要とする唯一の識別子です。

非同期オーバーロードは、ファイルパス、ファイルパス+フォーマット別設定(PdfConfig、WordConfig …)、または Stream と拡張子でフォーマットを判別する FileInfo のいずれかを受け取ります。Web Forms のコードビハインドで非同期ページを使用しない場合は、OpenDocument が同じ 3 つの入力を同期的に提供します(パス、ファイル名付きストリーム、またはファイル名付きバイト配列)。

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

ウィジェットはトークンをクエリ文字列に含めて 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. と表示されたエラー画像。

エラー画像はステータス 200 の普通の PNG として送信されるため、ウィジェットはページがある場所に画像を表示できます。ステータスコードだけを監視するチェックは、実際のページ(数十〜数百 KB)とエラー画像(約 2 KB)を区別できません。

ドキュメントのクローズ

csharp
viewer.CloseDocument(token);

CloseDocument はセッションを削除し(ドキュメントエンジンとメモリが即座に解放されます)、現在のリクエストの ASP.NET セッションから secure-{token} エントリを削除し、トークンを無効化します。スライディング有効期限でも同様のクリーンアップは行われますが、大容量ドキュメントの場合はユーザーが作業を終えた瞬間にメモリを解放できるため推奨されます。ブラウザ側からは objViewer.Close(true) が同等のクローズリクエストを DocImage.axd に送ります。

重要ポイント

  • 1 つのオープンドキュメント = 1 つのセッション = 1 つのトークン。トークンはオープンした ASP.NET セッションに付与されます。
  • トークンはスライディングウィンドウで期限切れとなり、DocOptions.TimeOut を超えてアイドル状態が続くと再オープンが必要です。
  • Viewer は自由に解決・共有でき、状態はすべてセッションが保持します。

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