איך הצופה עובד
מחזור חיי בקשת המסמך
Doconut מציג מסמכים כתמונות ממוספרות המוגשות דרך middleware של ASP.NET Core. הבנת מחזור החיים — פתיחה, אסימון, בקשות דף, סגירה — מסבירה כמעט כל התנהגות שתצפו, כולל הודעות השגיאה.
שלושת החלקים הנעים
Viewer— השירות הציבורי שאתה מוזרק. הוא פותח מסמכים ומחזיר אסימוני סשן.- סשן המסמך — אובייקט בצד השרת המחזיק את המסמך הטעון, ממופה לאסימון ב
IMemoryCache. - ה‑middleware של Doconut — נוסף על ידי
UseDoconut(); משיב לכל בקשה שהווידג'ט של הדפדפן מבצע (pages,thumbnails,search,annotations, …), תמיד מאומת על ידי האסימון.
Viewer הוא חסר מצב — לפי תכנון
Viewer סגור, אינו מחזיק במצב מסמך לכל בקשה, ובכוונה לא מממש את IDisposable. סשנים קיימים באופן עצמאי במנהל הסשנים ומנוקים על ידי פקיעת המטמון או CloseDocument(token) מפורש.
הזרק אותו בכל מקום שבו אתה צריך אותו:
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync($"files/{fileName}");
return Results.Content(token, "text/plain");
});מה קורה בתוך OpenDocumentAsync
- שער רישיון. רישיון שנדחה או שפג תוקפו (ברשימה שחורה, שונה, או בנייה מחוץ לחלון העדכון של הרישיון) זורק
LicenseExceptionמיידית, עם סיבת הדחייה כהודעה — הפתיחה לעולם לא מתדרדרת בשקט עבור רישיון לא תקף (בניגוד לחסר). רישיון זמני או מנוי שפג תוקפו לפי לוח השנה הוא היוצא מן הכלל: הוא לא זורק — הוא מתדרדר למים. - יצירת סשן. מפעל הצופה בוחר את הצופה המתאים לפורמט עבור סיומת הקובץ וטוען את המסמך (ראו Rendering Pipeline). הסשן נשמר ב
IMemoryCacheתחת אסימון GUID חדש עם פג תוקף מתגלגל —DocOptions.TimeOutדקות, ברירת מחדל 60. כל בקשת דף מאפסת את השעון. - רישום אבטחה. עם
UnsafeMode = false(ברירת המחדל), האסימון קשור לסשן ASP.NET של הקורא: סמןsecure-{token}נכתב לתוך הסשן, כך שרק סשן הדפדפן שפתח את המסמך יכול לבקש את הדפים שלו. - האסימון מוחזר. הוא האסימון היחיד לכל מה שבא אחרי.
שלושת העומסים השונים נבדלים רק בקלט: נתיב קובץ, נתיב קובץ בתוספת תצורת פורמט‑לפי (PdfConfig, WordConfig, …), או Stream בתוספת FileInfo שהרחבה שלו מניעה את זיהוי הפורמט.
איך הווידג'ט מקבל דפים
הווידג'ט של הלקוח קורא ל‑Doconut middleware עם האסימון במחרוזת השאילתה. מה שה‑middleware עושה תלוי בבקשה:
| שאילתה | מטרה |
|---|---|
?token=…&page=N | תמונת דף מעובדת (PNG) |
?token=…&page=N&thumb=1 | תמונה ממוזערת |
?token=…&zoom=… | עיבוד דף מוגדל |
?token=…&search=term | חיפוש טקסט מלא (בקרת רישיון) |
?token=…&bookmarks | מתאר המסמך/סימניות |
?token=…© / &showlinks / &fileFormat / &meta | העתקת טקסט, קישורים, מידע פורמט, מטא‑נתונים טכניים של DICOM |
?token=…&action=rotate/flip/close | פעולות דף וסגירה מפורשת |
?token=…&AnnSave=… / &AnnLoad | שמירת/טעינת אנוטציות |
כל אחד מהנתיבים האלה מתבצע אימות תחילה:
- אין אסימון → ה‑middleware מחזיר 404 (או באנר גרסה כאשר
ShowDoconutInfo = true). - אסימון לא ידוע או שפג תוקפו → תמונת שגיאה עם
Document session not found. Please re-open document. - חסרה middleware של סשן (עם
UnsafeMode = false) → HTTP 500 עםSession middleware not configured. Call UseSession() before UseDoconut(). - האסימון נפתח על ידי סשן דפדפן שונה → תמונת שגיאה עם
You Are Not Authorized To View This Page.
סגירת מסמך
viewer.CloseDocument(token);CloseDocument מסיר את הסשן מהמטמון (שמשחרר את מנוע המסמך הבסיסי ומשחרר את הזיכרון שלו מייד), מוחק את הסמן secure-{token}, ומבטל את ההרשאה לגישה. קריאה אליו היא אופציונלית — פג תוקף מתגלגל עושה את הניקוי האוטומטי — אך עבור מסמכים גדולים זו הדרך המנומסת לשחרר זיכרון ברגע שהמשתמש מסיים.
מסקנות
- מסמך פתוח אחד = סשן אחד = אסימון אחד. אסימונים הם לכל סשן דפדפן, לא לכתובות URL גלובליות.
- האסימון פג בתוקף בחלון מתגלגל; צופה שנשאר במצב מנוחה מעבר ל
DocOptions.TimeOutצריך פתיחה מחדש. Viewerניתן להזרקה ושיתוף חופשי; סשנים נושאים את כל המצב.
האם דף זה היה מועיל?