Autor | Beitrag |
---|
000 23.12.2012, 21:45 Alcapone |
Hallo Thewall! Ich arbeite gerade an einem Server mit connection-pooling (disconnect & timeout detection ohne polling) um eine möglichst hohe Anzahl an HTTP Requests zu verarbeiten und in unter 50 ms zu beantworten. Dabei bin ich auf 3 Probleme gestoßen: Wenn der Client Daten zum Server Sendet, die Antwort vom Server aber nicht ließt/emfängt, dann blockiert die Recieve Methode des Servers nicht mehr und der Thread verwandelt sich in einen Zombie (while true schleife). Zweites Problem: ich hab keine Idee, wie ich den HTTP Parser implementieren muss. Folgende Klassen habe ich: Drittes Problem: Soweit viel Text, aber vlt gibts ja nen findigen, der die antworten kennt. --"Everything, that can go wrong, will go wrong" Murphy's Law |
Profil || Suche |
001 25.12.2012, 09:57 Alcapone |
Inzwischen habe ich meine Gedanken reifen lassen. Das erste Problem existiert weiterhin, ich habe noch keine Möglichkeit gefunden, zu prüfen, ob der verbundene Client meine Daten auch empfängt und der Recieve Vorgang blockiert wird. Zum zweiten Problem: Es wird keinen Connection-Pool mehr geben, nur noch einen Threadpool, der alle Threads beinhaltet. Ein Thread steuert eine Verbindung, das HTTP parsing und die weitere Verarbeitung der Daten. Zum dritten Problem habe ich auch eine Lösung gefunden. Die Connection löst ein OnDataRecieved Event aus, das nicht unbedingt einen kompletten HTTP Request beinhalten muss. Beim Event werden die empfangenen Daten mitgeliefert und an den vom Thread ebenfalls instanzierten HTTPHandler weitergegeben, der ein OnHttpMessageCompleted Event ausführt wenn ein Vollständiger HTTP Request empfangen wurde. Ob ein Request Vollständig ist, wird anhand des HTTP Headers Content-Length geprüft. Ich hoffe, das ist halbwegs sinnvoll durchdacht... --"Everything, that can go wrong, will go wrong" Murphy's Law |
Profil || Suche |
002 02.01.2013, 04:33 flokralle |
Zum ersten Problem: |
Profil || Suche |
003 03.01.2013, 23:32 Alcapone |
Hallo flokralle, danke für den Tip, darauf hab ich nicht geachtet. Gilt das auch für den nonblocking mode? MSDN sagt da nur lapidar: So wie ich das verstanden habe, wartet der Server nicht auf eine Rückantwort vom Client, die ihm sagt, wieviele Bytes empfangen wurden (nonblocking). Nichtsdestotrotz werde ich das morgen mal ausprobieren und erfolg oder misserfolg hier schildern. --"Everything, that can go wrong, will go wrong" Murphy's Law Dieser Beitrag wurde am 03.01.2013 um 23:42 von Alcapone bearbeitet. |
Profil || Suche |
004 04.01.2013, 13:00 flokralle |
Nein, damit ist nur gemeint, dass Send eventuell nicht den kompletten Buffer sendet und man deshalb prüfen soll ob der Rückgabewert von send so groß wie die Größe des Buffer ist und nicht eventuell kleiner. (wenn z.B. während dem send die Verbindung abgebrochen wird) -- |
Profil || Suche |
005 23.10.2013, 14:21 Alcapone |
Falls es jemanden noch interessiert: Seit DotNet 3.5 gibt es SocketAsyncEventArgs, die speziell für hochperformante Serverapplikationen eingeführt wurde, da das allozieren der IAsyncResult Objekte hiermit wegfällt. Bezüglich Threading und Blocking: Bezüglich Protokollen: Eine (HTTP) Message ist dann fertig, wenn der Header + alle bytes von dem Headerfeld Content-Length empfangen wurden. Header, die kein Content-Length Feld enthalten, werden bis zum \r\n\r\n gelesen, es gibt dann keinen Content, daher wird nur der Header in der Message-Pipeline abgelegt. Es sollte ein Timeout festgelegt werden, bis wann Header und Contentdaten empfangen werden, da sonst unnötig Ressourcen vom Server blockiert werden. --"Everything, that can go wrong, will go wrong" Murphy's Law |
Profil || Suche |