Enregistrement du temps – Conversion HTML – Exemple C#
Dans cet article, vous trouverez un exemple d’utilisation de gestionnaires de messages personnalisés pour convertir le code HTML d’une archive ZIP en PDF et enregistrer le temps d’exécution de ce processus.
Parfois, afin d’optimiser les performances, vous pouvez avoir besoin de connaître le temps d’exécution d’une requête web. Par exemple, vous voulez savoir combien de temps prend la conversion d’un fichier HTML d’une archive ZIP en PDF.
Enregistrement du temps d’exécution
Création d’un gestionnaire de messages pour une implémentation de schéma personnalisé
Créons un gestionnaire personnalisé que vous pourrez utiliser pour la mise en œuvre d’un schéma (protocole) personnalisé. Suivez les étapes suivantes :
- Utilisez l’espace de nommage nécessaire, à savoir Aspose.Html.Net.
- Définissez votre propre classe CustomSchemaMessageHandler qui sera dérivée de la classe MessageHandler.
- Initialiser une instance de la classe CustomSchemaMessageHandler et lui définir une propriété Filter.
- Créez la classe CustomSchemaMessageFilter dérivée de la classe MessageFilter.
- Surchargez la méthode Match() de la classe MessageFilter pour implémenter le comportement du gestionnaire de messages personnalisé.
L’extrait de code suivant montre comment créer la classe CustomSchemaMessageHandler :
1// Monitor network requests by custom protocol in C # using schema-based message filter and handler
2
3// Define the CustomSchemaMessageFilter class that is derived from the MessageFilter class
4class CustomSchemaMessageFilter : MessageFilter
5{
6 private readonly string schema;
7 public CustomSchemaMessageFilter(string schema)
8 {
9 this.schema = schema;
10 }
11 // Override the Match() method
12 public override bool Match(INetworkOperationContext context)
13 {
14 return string.Equals(schema, context.Request.RequestUri.Protocol.TrimEnd(':'));
15 }
16}
17
18// Define the CustomSchemaMessageHandler class that is derived from the MessageHandler class
19abstract class CustomSchemaMessageHandler : MessageHandler
20{
21 // Initialize an instance of the CustomSchemaMessageHandler class
22 protected CustomSchemaMessageHandler(string schema)
23 {
24 Filters.Add(new CustomSchemaMessageFilter(schema));
25 }
26}
Le constructeur CustomSchemaMessageHandler(schema
) instancie l’objet CustomSchemaMessageHandler et prend le schema
comme paramètre. La méthode Add() ajoute l’objet CustomSchemaMessageFilter à la fin de la collection. La méthode Match() teste si un contexte
répond aux critères du filtre.
Création du ZipFileSchemaMessageHandler pour travailler avec des archives ZIP
L’extrait de code suivant montre comment créer la classe ZipFileSchemaMessageHandler pour travailler avec des archives ZIP :
1// Handle zip file protocol requests in c#
2
3// Define the ZipFileSchemaMessageHandler class that is derived from the CustomSchemaMessageHandler class
4class ZipFileSchemaMessageHandler : CustomSchemaMessageHandler
5{
6 private readonly Archive archive;
7
8 public ZipFileSchemaMessageHandler(Archive archive) : base("zip-file")
9 {
10 this.archive = archive;
11 }
12
13 // Override the Invoke() method
14 public override void Invoke(INetworkOperationContext context)
15 {
16 string pathInsideArchive = context.Request.RequestUri.Pathname.TrimStart('/').Replace("\\", "/");
17 Stream stream = GetFile(pathInsideArchive);
18
19 if (stream != null)
20 {
21 // If a resource is found in the archive, then return it as a Response
22 ResponseMessage response = new ResponseMessage(HttpStatusCode.OK);
23 response.Content = new StreamContent(stream);
24 response.Headers.ContentType.MediaType = MimeType.FromFileExtension(context.Request.RequestUri.Pathname);
25 context.Response = response;
26 }
27 else
28 {
29 context.Response = new ResponseMessage(HttpStatusCode.NotFound);
30 }
31
32 // Invoke the next message handler in the chain
33 Next(context);
34 }
35
36 Stream GetFile(string path)
37 {
38 ArchiveEntry result = archive
39 .Entries
40 .FirstOrDefault(x => x.Name == path);
41 return result?.Open();
42 }
43}
Dans l’exemple ci-dessus, la recherche d’une ressource (archive zip) à son URI est réalisée. Si une ressource est trouvée, la méthode FromFileExtension() renvoie le MimeType de la ressource.
Gestionnaire de messages pour une requête Web Enregistrement du temps d’exécution
L’extrait de code suivant montre comment créer StartRequestDurationLoggingMessageHandler et StopRequestDurationLoggingMessageHandler pour enregistrer le temps nécessaire à l’exécution d’une requête web.
1// Track and log HTTP request durations using C# message handlers
2
3// Define the RequestDurationLoggingMessageHandler class that is derived from the MessageHandler class
4abstract class RequestDurationLoggingMessageHandler : MessageHandler
5{
6 private static ConcurrentDictionary<Url, Stopwatch> requests = new ConcurrentDictionary<Url, Stopwatch>();
7
8 protected void StartTimer(Url url)
9 {
10 requests.TryAdd(url, Stopwatch.StartNew());
11 }
12
13 protected TimeSpan StopTimer(Url url)
14 {
15 Stopwatch timer = requests[url];
16 timer.Stop();
17 return timer.Elapsed;
18 }
19}
20
21class StartRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
22{
23 // Override the Invoke() method
24 public override void Invoke(INetworkOperationContext context)
25 {
26 // Start the stopwatch
27 StartTimer(context.Request.RequestUri);
28
29 // Invoke the next message handler in the chain
30 Next(context);
31 }
32}
33
34class StopRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
35{
36 // Override the Invoke() method
37 public override void Invoke(INetworkOperationContext context)
38 {
39 // Stop the stopwatch
40 TimeSpan duration = StopTimer(context.Request.RequestUri);
41
42 // Print the result
43 Debug.WriteLine($"Elapsed: {duration:g}, resource: {context.Request.RequestUri.Pathname}");
44
45 // Invoke the next message handler in the chain
46 Next(context);
47 }
48}
Ajout des gestionnaires de messages au pipeline
Le concept clé du fonctionnement des gestionnaires de messages consiste à les enchaîner les uns aux autres. Nous avons créé plusieurs gestionnaires de messages et devons les ajouter au pipeline dans un ordre spécifique pour mettre en œuvre l’exemple de l’enregistrement du temps de conversion du HTML d’une archive ZIP en PDF. Exécutons les étapes suivantes :
- Créer une instance de la classe Configuration.
- Réaliser le schéma personnalisé ZIP. Utilisez la méthode Add() pour ajouter ZipFileSchemaMessageHandler à la fin du pipeline.
- Exécuter l’enregistrement de la durée. Utilisez la méthode Insert() pour ajouter le StartRequestDurationLoggingMessageHandler en premier dans le pipeline, et la méthode Add() pour ajouter le StopRequestDurationLoggingMessageHandler à la fin du pipeline.
- Initialise un document HTML avec la configuration spécifiée.
- Créer le dispositif PDF et convertir le HTML en PDF.
1// Implement custom zip schema with request duration logging using C# message handlers
2
3// Add this line before you try to use the 'IBM437' encoding
4System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
5
6// Prepare path to a source zip file
7string documentPath = Path.Combine(DataDir, "test.zip");
8
9// Prepare path for converted file saving
10string savePath = Path.Combine(OutputDir, "zip-to-pdf-duration.pdf");
11
12// Create an instance of the Configuration class
13using Configuration configuration = new Configuration();
14INetworkService service = configuration.GetService<INetworkService>();
15MessageHandlerCollection handlers = service.MessageHandlers;
16
17// Custom Schema: ZIP. Add ZipFileSchemaMessageHandler to the end of the pipeline
18handlers.Add(new ZipFileSchemaMessageHandler(new Archive(documentPath)));
19
20// Duration Logging. Add the StartRequestDurationLoggingMessageHandler at the first place in the pipeline
21handlers.Insert(0, new StartRequestDurationLoggingMessageHandler());
22
23// Add the StopRequestDurationLoggingMessageHandler to the end of the pipeline
24handlers.Add(new StopRequestDurationLoggingMessageHandler());
25
26// Initialize an HTML document with specified configuration
27using HTMLDocument document = new HTMLDocument("zip-file:///test.html", configuration);
28
29// Create the PDF Device
30using PdfDevice device = new PdfDevice(savePath);
31
32// Render ZIP to PDF
33document.RenderTo(device);
Le constructeur Configuration() crée une instance de la classe
Configuration. Une fois la configuration créée, les méthodes GetService<INetworkService>()
, MessageHandlers.Add()
et MessageHandlers.Insert()
sont invoquées. Les méthodes Insert() et Add() ajoutent les gestionnaires de messages personnalisés à la collection de gestionnaires de messages existants. La figure montre la chaîne de gestionnaires de messages pour cet exemple :
Note: Le constructeur
HTMLDocument(address, configuration
) prend le chemin absolu vers l’archive ZIP. Mais toutes les ressources associées ont des chemins relatifs dans le document HTML et dans le code de l’exemple.
Vous pouvez télécharger les exemples complets et les fichiers de données sur GitHub.