วิธีการทำงานของ Viewer

วงจรการร้องขอเอกสาร

Doconut แสดงเอกสารเป็นภาพที่แบ่งหน้าและให้บริการผ่าน middleware ของ ASP.NET Core การเข้าใจวงจรชีวิต — การเปิด, โทเคน, การร้องขอหน้า, การปิด — จะอธิบายพฤติกรรมเกือบทั้งหมดที่คุณจะสังเกตเห็น รวมถึงข้อความแสดงข้อผิดพลาด

สามส่วนที่ทำงานร่วมกัน

  • Viewer — บริการสาธารณะที่คุณฉีดเข้าไป มันเปิดเอกสารและคืนค่าโทเคนเซสชัน
  • The document session — วัตถุฝั่งเซิร์ฟเวอร์ที่เก็บเอกสารที่โหลดแล้ว โดยใช้โทเคนใน IMemoryCache เป็นคีย์
  • The Doconut middleware — ถูกเพิ่มโดย UseDoconut(); ตอบสนองต่อทุกคำขอที่วิดเจ็ตเบราว์เซอร์ทำ (pages, thumbnails, search, annotations, …) โดยยืนยันตัวตนด้วยโทเคนเสมอ

Viewer เป็นแบบไม่มีสถานะ — ตามการออกแบบ

Viewer ถูกปิดกั้น, ไม่เก็บสถานะเอกสารต่อคำขอ, และโดยเจตนา ไม่ ทำการ implement IDisposable. เซสชันดำรงอยู่แยกจากกันในตัวจัดการเซสชันและจะถูกทำความสะอาดโดยการหมดอายุของแคชหรือโดย CloseDocument(token) ที่ชัดเจน

ฉีดเข้าไปที่ใดก็ได้ที่คุณต้องการ:

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

สิ่งที่เกิดขึ้นภายใน OpenDocumentAsync

  1. License gate. ใบอนุญาตที่ถูกปฏิเสธหรือหมดอายุเวอร์ชัน (อยู่ในรายการดำ, ถูกดัดแปลง, หรือเป็นการสร้างนอกหน้าต่างการอัปเดตของใบอนุญาต) จะโยน LicenseException ทันที, พร้อมเหตุผลการปฏิเสธเป็นข้อความ — การเปิดจะไม่ลดคุณภาพอย่างเงียบสำหรับใบอนุญาตที่ไม่ถูกต้อง (ตรงข้ามกับที่ไม่มี) ใบอนุญาต Temporary หรือ subscription ที่หมดอายุตามปฏิทินเป็นข้อยกเว้น: มันจะไม่โยน — แต่จะลดคุณภาพเป็นลายน้ำ
  2. Session creation. โรงงาน viewer เลือก viewer ที่เหมาะสมกับรูปแบบไฟล์ตามส่วนขยายและโหลดเอกสาร (ดู Rendering Pipeline). เซสชันถูกเก็บใน IMemoryCache ภายใต้โทเคน GUID ใหม่พร้อม การหมดอายุแบบเลื่อน — DocOptions.TimeOut นาที, ค่าเริ่มต้น 60. ทุกการร้องขอหน้า จะรีเซ็ตนาฬิกา
  3. Security registration. ด้วย UnsafeMode = false (ค่าเริ่มต้น), โทเคนจะถูกผูกกับเซสชัน ASP.NET ของผู้เรียก: มีมาร์กเกอร์ secure-{token} ถูกเขียนลงในเซสชัน, ดังนั้นเฉพาะเซสชันเบราว์เซอร์ที่เปิดเอกสารเท่านั้นที่สามารถร้องขอหน้าของมันได้
  4. The token is returned. มันเป็นข้อมูลประจำตัวเดียวสำหรับทุกอย่างที่ตามมา

การโอเวอร์โหลดสามแบบแตกต่างกันเพียงในอินพุต: เส้นทางไฟล์, เส้นทางไฟล์พร้อมการกำหนดค่าตามรูปแบบ (PdfConfig, WordConfig, …), หรือ Stream พร้อมกับ FileInfo ที่ส่วนขยายของมันกำหนดการตรวจจับรูปแบบ

วิธีที่วิดเจ็ตรับหน้า

วิดเจ็ตลูกค้าจะเรียก Doconut middleware พร้อมโทเคนใน query string. สิ่งที่ middleware ทำขึ้นอยู่กับคำขอ:

คำค้นจุดประสงค์
?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การกระทำบนหน้าและการปิดอย่างชัดเจน
?token=…&AnnSave=… / &AnnLoadบันทึก/โหลดคำอธิบายประกอบ

ทุกเส้นทางเหล่านี้จะตรวจสอบความถูกต้องก่อน:

  • No token → middleware จะคืนค่า 404 (หรือแบนเนอร์เวอร์ชันเมื่อ ShowDoconutInfo = true).
  • Unknown or expired token → รูปภาพข้อผิดพลาดพร้อม Document session not found. Please re-open document.
  • Session middleware missing (กับ UnsafeMode = false) → HTTP 500 พร้อม Session middleware not configured. Call UseSession() before UseDoconut().
  • Token opened by a different browser session → รูปภาพข้อผิดพลาดพร้อม You Are Not Authorized To View This Page.

การปิดเอกสาร

csharp
viewer.CloseDocument(token);

CloseDocument ลบเซสชันออกจากแคช (ซึ่งทำลายเอนจินเอกสารพื้นฐานและปล่อยหน่วยความจำทันที), ลบมาร์กเกอร์ secure-{token}, และเพิกถอนการให้สิทธิ์การเข้าถึง. การเรียกใช้เป็นทางเลือก — การหมดอายุแบบเลื่อนจะทำความสะอาดเดียวกันโดยอัตโนมัติ — แต่สำหรับเอกสารขนาดใหญ่เป็นวิธีที่สุภาพในการปล่อยหน่วยความจำเมื่อผู้ใช้เสร็จสิ้น

สิ่งที่ควรจำ

  • เอกสารที่เปิดหนึ่งไฟล์ = เซสชันหนึ่ง = โทเคนหนึ่ง. โทเคนเป็นต่อเซสชันเบราว์เซอร์, ไม่ใช่ URL ทั่วโลก.
  • โทเคนหมดอายุในหน้าต่างแบบเลื่อน; viewer ที่ค้างอยู่โดยไม่มีการใช้งานเกินกว่า DocOptions.TimeOut ต้องเปิดใหม่.
  • Viewer สามารถฉีดและแชร์ได้อย่างอิสระ; เซสชันบรรจุสถานะทั้งหมด.

หน้านี้เป็นประโยชน์หรือไม่?