Πώς Λειτουργεί ο Viewer
Ο κύκλος ζωής του αιτήματος εγγράφου
Doconut αποδίδει έγγραφα ως σελιδοποιημένες εικόνες που εξυπηρετούνται μέσω του middleware ASP.NET Core. Η κατανόηση του κύκλου ζωής — άνοιγμα, διακριτικό, αιτήματα σελίδων, κλείσιμο — εξηγεί σχεδόν κάθε συμπεριφορά που θα παρατηρήσετε, συμπεριλαμβανομένων των μηνυμάτων σφάλματος.
Τα τρία κινούμενα μέρη
Viewer— η δημόσια υπηρεσία που ενσωματώνετε. Ανοίγει έγγραφα και επιστρέφει διακριτικά συνεδρίας.- Η συνεδρία εγγράφου — ένα αντικείμενο στο διακομιστή που κρατά το φορτωμένο έγγραφο, με κλειδί ένα διακριτικό στο
IMemoryCache. - Το Doconut middleware — προστίθεται με
UseDoconut()· απαντά σε κάθε αίτημα που κάνει το widget του προγράμματος περιήγησης (pages,thumbnails,search,annotations, …), πάντα αυθεντικοποιημένο με το διακριτικό.
Το Viewer είναι χωρίς κατάσταση — σχεδιαστικά
Το Viewer είναι sealed, δεν διατηρεί κατάσταση εγγράφου ανά αίτημα και σκόπιμα δεν υλοποιεί το 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, με τον λόγο απόρριψης ως μήνυμα — το άνοιγμα δεν υποβαθμίζεται σιωπηρά για άκυρη (αντί για απουσία) άδεια. Μια λήξη ημερολογίου για προσωρινή ή συνδρομητική άδεια είναι η εξαίρεση: δεν ρίχνει — υποβαθμίζεται σε υδατογράφημα. - Δημιουργία συνεδρίας. Η εργοστασιακή λειτουργία του viewer επιλέγει το σωστό viewer μορφής για την επέκταση του αρχείου και φορτώνει το έγγραφο (δείτε το Rendering Pipeline). Η συνεδρία αποθηκεύεται στο
IMemoryCacheκάτω από ένα νέο GUID διακριτικό με ολική λήξη —DocOptions.TimeOutλεπτά, προεπιλογή 60. Κάθε αίτημα σελίδας επαναρυθμίζει το ρολόι. - Καταχώρηση ασφαλείας. Με
UnsafeMode = false(η προεπιλογή), το διακριτικό συνδέεται με τη συνεδρία ASP.NET του καλούντος: ένας δείκτηςsecure-{token}γράφεται στη συνεδρία, ώστε μόνο η συνεδρία του προγράμματος περιήγησης που άνοιξε το έγγραφο να μπορεί να ζητήσει τις σελίδες του. - Το διακριτικό επιστρέφεται. Είναι το μοναδικό διαπιστευτήριο για όλα τα επόμενα.
Οι τρεις υπερφορτώσεις διαφέρουν μόνο στην είσοδο: μια διαδρομή αρχείου, μια διαδρομή αρχείου συν ένα config ανά μορφή (PdfConfig, WordConfig, …), ή ένα Stream συν ένα FileInfo του οποίου η επέκταση καθορίζει την ανίχνευση μορφής.
Πώς το widget λαμβάνει σελίδες
Το widget του πελάτη καλεί το Doconut middleware με το διακριτικό στη συμβολοσειρά ερωτήματος. Η ενέργεια του middleware εξαρτάται από το αίτημα:
| Ερώτημα | Σκοπός |
|---|---|
?token=…&page=N | Εικόνα σελίδας (PNG) |
?token=…&page=N&thumb=1 | Μικρογραφία |
?token=…&zoom=… | Απόδοση σελίδας με ζουμ |
?token=…&search=term | Αναζήτηση πλήρους κειμένου (με έλεγχο άδειας) |
?token=…&bookmarks | Δομή εγγράφου/σελιδοδείκτες |
?token=…© / &showlinks / &fileFormat | Αντιγραφή κειμένου, υπερσυνδέσεις και πληροφορίες μορφής |
?token=…&meta | Τεχνικά μεταδεδομένα DICOM· επιστρέφει 501 για συνεδρία DICOM σε .NET 6 |
?token=…&action=rotate/flip/close | Ενέργειες σελίδας και ρητό κλείσιμο |
?token=…&AnnSave=… / &AnnLoad | Αποθήκευση/φόρτωση σχολίων |
Κάθε μία από αυτές τις διαδρομές επικυρώνεται πρώτα:
- Χωρίς διακριτικό → το middleware επιστρέφει 404 (ή μια διαφήμιση έκδοσης όταν
ShowDoconutInfo = true). - Άγνωστο ή ληγμένο διακριτικό → μια εικόνα σφάλματος με το κείμενο «Δεν βρέθηκε η συνεδρία εγγράφου. Παρακαλώ ανοίξτε ξανά το έγγραφο.»
- Το middleware συνεδρίας δεν έχει ρυθμιστεί (με
UnsafeMode = false) → HTTP 500 με το κείμενο «Το middleware συνεδρίας δεν έχει ρυθμιστεί. Καλέστε UseSession() πριν από UseDoconut().» - Διακριτικό ανοιγμένο από διαφορετική συνεδρία προγράμματος περιήγησης → μια εικόνα σφάλματος με το κείμενο «Δεν έχετε εξουσιοδότηση να δείτε αυτή τη σελίδα.»
Κλείσιμο εγγράφου
viewer.CloseDocument(token);CloseDocument αφαιρεί τη συνεδρία από την προσωρινή μνήμη (που απελευθερώνει τη βασική μηχανή εγγράφου και ελευθερώνει τη μνήμη της αμέσως), διαγράφει το δείκτη secure-{token} και ανακαλεί την άδεια πρόσβασης. Η κλήση του είναι προαιρετική — η ολική λήξη κάνει την ίδια εκκαθάριση αυτόματα — αλλά για μεγάλα έγγραφα είναι ο ευγενικός τρόπος να απελευθερώσετε τη μνήμη τη στιγμή που ο χρήστης ολοκληρώνει.
Συμπεράσματα
- Ένα ανοιχτό έγγραφο = μία συνεδρία = ένα διακριτικό. Τα διακριτικά είναι ανά συνεδρία προγράμματος περιήγησης, όχι καθολικά URLs.
- Το διακριτικό λήγει σε ένα ολιστικό παράθυρο· ένας viewer που παραμένει αδρανής πέρα από το
DocOptions.TimeOutχρειάζεται νέο άνοιγμα. - Το
Viewerμπορεί να ενσωματωθεί και να μοιραστεί ελεύθερα· οι συνεδρίες μεταφέρουν όλη την κατάσταση.
Ήταν αυτή η σελίδα χρήσιμη;