# Manuelle (erweiterte) Einrichtung

Source: https://docs.sisk-framework.org/de/docs/advanced/manual-setup.html

Verwenden Sie die manuelle Einrichtung, wenn Sie die Serverkomponenten selbst zusammenstellen müssen, z. B. wenn ein Prozess mehrere Hosts, Ports, Router oder eine benutzerdefinierte Serverkonfiguration bereitstellen muss. Für die meisten Anwendungen ist die Builder‑API kürzer und sollte bevorzugt werden. Die manuelle Einrichtung ist nützlich, wenn Sie direkte Kontrolle über die vier Kernkomponenten haben möchten: einen `Router`, ein oder mehrere `ListeningHost`‑Objekte, eine `HttpServerConfiguration` und den endgültigen `HttpServer`.

Zuerst müssen wir das Request/Response‑Konzept verstehen. Es ist ganz einfach: Für jede Anfrage muss eine Antwort existieren. Sisk folgt diesem Prinzip ebenfalls. Lassen Sie uns eine Methode erstellen, die mit einer „Hello, World!“-Nachricht in HTML antwortet und dabei den Statuscode sowie die Header angibt.

```csharp
// Program.cs
using Sisk.Core.Http;
using Sisk.Core.Routing;

static HttpResponse IndexPage(HttpRequest request)
{
    HttpResponse indexResponse = new HttpResponse
    {
        Status = System.Net.HttpStatusCode.OK,
        Content = new HtmlContent(@"
            <html>
                <body>
                    <h1>Hello, world!</h1>
                </body>
            </html>
        ")
    };

    return indexResponse;
}
```

Der nächste Schritt besteht darin, diese Methode mit einer HTTP‑Route zu verknüpfen.

## Router

Router sind Abstraktionen von Anforderungsrouten und dienen als Brücke zwischen Anfragen und Antworten des Dienstes. Router verwalten Service‑Routen, Funktionen und Fehler.

Ein Router kann mehrere Routen besitzen, und jede Route kann unterschiedliche Operationen für diesen Pfad ausführen, z. B. eine Funktion ausführen, eine Seite bereitstellen oder eine Ressource vom Server liefern.

Lassen Sie uns unseren ersten Router erstellen und unsere `IndexPage`‑Methode mit dem Index‑Pfad verknüpfen.

```csharp
Router mainRouter = new Router();

mainRouter.MapGet("/", IndexPage);
```

Jetzt kann unser Router Anfragen empfangen und Antworten senden. Allerdings ist `mainRouter` nicht an einen Host oder einen Server gebunden, sodass er allein nicht funktioniert. Der nächste Schritt besteht darin, unser ListeningHost zu erstellen.

## Listening‑Hosts und Ports

Ein [ListeningHost](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.md) kann einen Router und mehrere Listening‑Ports für denselben Router hosten. Ein [ListeningPort](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningPort.md) ist ein Präfix, an dem der HTTP‑Server lauscht.

Hier können wir einen `ListeningHost` erstellen, der auf zwei Endpunkte für unseren Router verweist:

```csharp
ListeningHost myHost = new ListeningHost
{
    Router = mainRouter,
    Ports = new ListeningPort[]
    {
        new ListeningPort("http://localhost:5000/")
    }
};
```

Jetzt wird unser HTTP‑Server an den angegebenen Endpunkten lauschen und seine Anfragen an unseren Router weiterleiten.

## Serverkonfiguration

Die Serverkonfiguration ist für das meiste Verhalten des HTTP‑Servers selbst verantwortlich. In dieser Konfiguration können wir `ListeningHosts` mit unserem Server verknüpfen.

```csharp
HttpServerConfiguration config = new HttpServerConfiguration();
config.ListeningHosts.Add(myHost); // Fügt unser ListeningHost zu dieser Serverkonfiguration hinzu
```

Gemeinsame Serverkonfigurationsoptionen:

| Eigenschaft | Standard | Verwendung | Hinweise |
| --- | --- | --- | --- |
| [RemoteRequestsAction](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.RemoteRequestsAction.md) | `RequestListenAction.Accept` | Der Dienst sollte nicht‑lokale Anfragen ablehnen, es sei denn, sie kommen über einen vertrauenswürdigen Reverse‑Proxy. | Setzen Sie `Drop` nur ein, wenn Ihre Bereitstellungstopologie klar ist. |
| [IncludeRequestIdHeader](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.IncludeRequestIdHeader.md) | `false` | Clients oder Proxies benötigen die Sisk‑Request‑ID im Antwort‑Header `X-Request-Id`. | Kombinieren Sie dies mit Logs, die `HttpRequest.RequestId` enthalten. |
| [IdleConnectionTimeout](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.IdleConnectionTimeout.md) | `120` seconds | Leerlauf‑Keep‑Alive‑Verbindungen sollten früher oder später geschlossen werden. | Dies wird von der HTTP‑Engine angewendet. |
| [NormalizeHeadersEncodings](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.NormalizeHeadersEncodings.md) | `false` | Sie erhalten Header mit einer Kodierungsinkonsistenz. | Dies verursacht Verarbeitungsaufwand; lassen Sie es deaktiviert, sofern nicht erforderlich. |
| [SendSiskHeader](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.SendSiskHeader.md) | `true` | Sie möchten den `X-Powered-By`‑Sisk‑Header verbergen oder sichtbar machen. | Deaktivieren Sie ihn für strengere Header‑Richtlinien in der Produktion. |
| [OptionsLogMode](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.OptionsLogMode.md) | `LogOutput.Both` | Sie möchten die durch die automatische `OPTIONS`‑Verarbeitung erzeugten Logs reduzieren oder umleiten. | Verwendet dieselben Log‑Modus‑Werte wie Routen. |
| [AsyncRequestProcessing](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.AsyncRequestProcessing.md) | `true` | Sie benötigen eine deterministische Einzel‑Request‑Verarbeitung für Diagnosen. | Das Deaktivieren reduziert den Durchsatz. |
| [DisposeDisposableContextValues](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.DisposeDisposableContextValues.md) | `true` | Request‑Bag‑Werte, die `IDisposable` implementieren, sollten automatisch freigegeben werden. | Aktiviert lassen, sofern die Besitzrechte nicht anderweitig verwaltet werden. |
| [ConvertIAsyncEnumerableIntoEnumerable](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ConvertIAsyncEnumerableIntoEnumerable.md) | `true` | Wert‑Handler sollten asynchrone Enumerables als blockierende Enumerable‑Werte erhalten. | Deaktivieren Sie dies, wenn Sie Ihre eigene Async‑Stream‑Verarbeitung implementieren. |
| [KeepAlive](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.KeepAlive.md) | `true` | Verbindungen sollten nach Antworten wiederverwendbar bleiben. | Deaktivieren Sie dies für Clients oder Zwischensysteme, die persistente Verbindungen nicht gut handhaben. |
| [ForceTrailingSlash](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ForceTrailingSlash.md) | `false` | GET‑Routen sollten zu einer URL mit abschließendem Schrägstrich umleiten. | Gilt nur für nicht‑regex‑basierte Routen. |
| [MaximumContentLength](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.MaximumContentLength.md) | `100 MB` | Request‑Bodies oder WebSocket‑Nachrichten benötigen ein anderes Größenlimit. | Der Standard war vor Sisk 1.7 `0` (unbegrenzt). Setzen Sie ihn auf `0`, um das Limit zu entfernen. |
| [EnableAutomaticResponseCompression](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.EnableAutomaticResponseCompression.md) | `false` | Antworten sollten automatisch komprimiert werden, wenn der Client dies unterstützt. | Vorhandene `CompressedContent`‑Antworten werden nicht erneut komprimiert. |

Als Nächstes können wir unseren HTTP‑Server erstellen:

```csharp
HttpServer server = new HttpServer(config);
server.Start();    // Startet den Server
Console.ReadKey(); // Verhindert, dass die Anwendung beendet wird
```

Jetzt können wir unsere ausführbare Datei kompilieren und unseren HTTP‑Server mit dem Befehl starten:

```bash
dotnet watch
```

Zur Laufzeit öffnen Sie Ihren Browser und navigieren zum Server‑Pfad; Sie sollten sehen:

<img src="/assets/img/localhost.png" >
