Cách hoạt động của Viewer

Vòng đời yêu cầu tài liệu

Doconut hiển thị tài liệu dưới dạng hình ảnh phân trang được phục vụ qua middleware ASP.NET Core. Hiểu vòng đời — mở, token, yêu cầu trang, đóng — giải thích hầu hết các hành vi bạn sẽ quan sát, bao gồm cả các thông báo lỗi.

Ba thành phần hoạt động

  • Viewer — dịch vụ công cộng bạn tiêm vào. Nó mở tài liệu và trả về token phiên.
  • Phiên tài liệu — một đối tượng phía máy chủ giữ tài liệu đã tải, được khóa bằng token trong IMemoryCache.
  • Middleware Doconut — được thêm bởi UseDoconut(); trả lời mọi yêu cầu mà widget trình duyệt gửi (pages, thumbnails, search, annotations, …), luôn được xác thực bằng token.

Viewer không có trạng thái — theo thiết kế

Viewer được đóng gói, không giữ trạng thái tài liệu theo yêu cầu, và cố ý không triển khai IDisposable. Các phiên tồn tại độc lập trong trình quản lý phiên và được dọn dẹp bằng việc hết thời gian cache hoặc bằng cách gọi CloseDocument(token) một cách rõ ràng.

Tiêm nó vào bất cứ nơi nào bạn cần:

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

Những gì xảy ra bên trong OpenDocumentAsync

  1. Cổng giấy phép. Một giấy phép bị từ chối hoặc đã hết hạn phiên bản (bị đưa vào danh sách đen, bị can thiệp, hoặc một bản dựng ngoài thời gian cập nhật của giấy phép) sẽ ném ra LicenseException ngay lập tức, với lý do từ chối làm thông điệp — việc mở sẽ không giảm chất lượng một cách âm thầm cho giấy phép không hợp lệ (khác với trường hợp không có giấy phép). Giấy phép tạm thời hoặc thuê bao đã hết hạn lịch là ngoại lệ: nó không ném lỗi — nó giảm xuống watermark.
  2. Tạo phiên. Nhà máy viewer chọn viewer định dạng phù hợp cho phần mở rộng tệp và tải tài liệu (xem Quy trình Render). Phiên được lưu trong IMemoryCache dưới một token GUID mới với thời gian hết hạn trượtDocOptions.TimeOut phút, mặc định 60. Mỗi yêu cầu trang sẽ đặt lại đồng hồ.
  3. Đăng ký bảo mật. Với UnsafeMode = false (mặc định), token được gắn với phiên ASP.NET của người gọi: một dấu secure-{token} được ghi vào phiên, vì vậy chỉ phiên trình duyệt đã mở tài liệu mới có thể yêu cầu các trang của nó.
  4. Token được trả về. Đây là thông tin xác thực duy nhất cho mọi thao tác tiếp theo.

Ba phương thức overload chỉ khác nhau ở đầu vào: một đường dẫn tệp, một đường dẫn tệp cộng với cấu hình định dạng riêng (PdfConfig, WordConfig, …), hoặc một Stream cộng với một FileInfo mà phần mở rộng quyết định định dạng phát hiện.

Cách widget lấy các trang

Widget client gọi middleware Doconut với token trong chuỗi truy vấn. Middleware sẽ thực hiện gì phụ thuộc vào yêu cầu:

Truy vấnMục đích
?token=…&page=NHình ảnh trang đã render (PNG)
?token=…&page=N&thumb=1Hình thu nhỏ
?token=…&zoom=…Render trang phóng to
?token=…&search=termTìm kiếm toàn văn (có kiểm soát giấy phép)
?token=…&bookmarksĐề cương tài liệu/dấu trang
?token=…&copy / &showlinks / &fileFormatSao chép văn bản, liên kết, và thông tin định dạng
?token=…&metaSiêu dữ liệu kỹ thuật DICOM; trả về 501 cho phiên DICOM trên .NET 6
?token=…&action=rotate/flip/closeHành động trang và đóng rõ ràng
?token=…&AnnSave=… / &AnnLoadLưu/tải chú thích

Mỗi đường dẫn này đều được kiểm tra trước:

  • Không có token → middleware trả về 404 (hoặc biểu ngữ phiên bản khi ShowDoconutInfo = true).
  • Token không xác định hoặc đã hết hạn → hình ảnh lỗi với Document session not found. Please re-open document.
  • Middleware phiên bị thiếu (với UnsafeMode = false) → HTTP 500 với Session middleware not configured. Call UseSession() before UseDoconut().
  • Token được mở bởi một phiên trình duyệt khác → hình ảnh lỗi với You Are Not Authorized To View This Page.

Đóng tài liệu

csharp
viewer.CloseDocument(token);

CloseDocument xóa phiên khỏi bộ nhớ cache (điều này giải phóng engine tài liệu nền và giải phóng bộ nhớ ngay lập tức), xóa dấu secure-{token}, và thu hồi quyền truy cập. Gọi hàm này là tùy chọn — thời gian hết hạn trượt sẽ tự động thực hiện dọn dẹp tương tự — nhưng đối với tài liệu lớn, đây là cách lịch sự để giải phóng bộ nhớ ngay khi người dùng hoàn thành.

Những điểm cần nhớ

  • Một tài liệu mở = một phiên = một token. Token thuộc về mỗi phiên trình duyệt, không phải URL toàn cục.
  • Token hết hạn theo cửa sổ trượt; nếu viewer không hoạt động quá DocOptions.TimeOut thì cần mở lại.
  • Viewer có thể được tiêm và chia sẻ tự do; các phiên mang toàn bộ trạng thái.

Trang này có hữu ích không?