| Autor |
Beitrag |
ase
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Mi 26.01.05 13:46
Hallo
Ich will einen Chat server schreiben. Ich bin gerade dabei mir Informationen einzuholen. Die frage ist, wie machen es die bekannten Emule Server 900.000 Verbindungen zu halten und zu versorgen? Fakt ist, pro Verbindung ein Thread ist Unsinn. Erstmal ist das verschwendung und dann ja bei 900K Verbindungen nicht möglich. Ich bin momentan auf WSAAsyncSelect() nur existiert da folgendes Problem: Ich habe wegen meiner einen Array von 900K Elementen. Jetzt bekomme ich eine window message von der WinSock verpasst, dass socket 1234 die Verbindung beendet hat. Jetzt müsste ich theoretisch meinen riesen Array locken, suchen und das Element löschen. Das Suchen allein dauert ja schon ewig aber dann auch noch zu locken so das andere Threads nicht ran können halte ich für unmöglich. Als nächsten Ansatz wollte ich parallel zu diesem Array noch einen zweiten Array setzen, in dem ich Mutexe oder CSs halte. Da wollte ich dann je 200 Elemente im 1. Array immer ein Element im 2. Array halten. Dann bräuchte nich den kompletten array locken, sondern immer nur Teile.
Warum kann ich einen Socket nicht mit einem von mir festgelegten 32 Bit Wert assoziieren? Gibt es da ne versteckte setSockOpt() Funktion oder so? Dann könnte ich den Index in meinem array speichern und bräuchte nicht suchen.
Hat da jemand irgendwelche Ideen oder Vorschläge?
Thx!
-EN
_________________ -EN
|
|
ScorpionKing
      
Beiträge: 1150
Win XP
|
Verfasst: Mi 26.01.05 13:49
Hallo ase,
hier eine Lösung, mit der du nicht alle Connections die du bekommst direkt verarbeitet werden müssen: eine MessageQueue (tipp von UGrohne, danke schön). In diese MessageQueue werden schnell alle Messages geschrieben und dann abgerufen! verstanden?????? ich poste auch gerne mal meine MessageQueue-Methode, muss sie aber erst rauskramen!!!!!!
MfG, Scorpion!
_________________ Aus dem Urlaub zurück!
|
|
ase 
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Mi 26.01.05 14:04
Hmm... darauf bin ich auch schon gekommen. Ich habe 80 Threads mit je einer Message Queue erstellt. Mittels WSAAsyncSelect verteile ich die einzelnen clients dann auf die Threads. Nur habe ich dann immernoch das Problem, dass ich bei 1000000 Clients pro Thread 12.500 Arrayeinträge durchsuchen müsste was mir immernoch zu lange dauert. An deinen Code wäre ich aber trotzdem interessiert. Vielleicht kann der mir ja den entscheidenen Ansatz verpassen
Thx!
-EN
_________________ -EN
|
|
ScorpionKing
      
Beiträge: 1150
Win XP
|
Verfasst: Mi 26.01.05 14:26
Yo gerne,
bitte schön:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| type TMessageQueue = class(TObject) private str: TStringList; public constructor Create; procedure AddMessage(text: string); function NextMessage: string; end;
constructor TMessageQueue.Create; begin str := TStringList.Create; end;
procedure TMessageQueue.AddMessage(text: string); begin str.Add(text); end;
function TMessageQueue.NextMessage: string; begin Result := str.Strings[0]; str.Delete(0); end; |
das ist die MessageQueue!!
Have fun, Scorpion!
_________________ Aus dem Urlaub zurück!
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 26.01.05 17:32
Moin!
@ScorpionKing: Ähm, IMHO mußt du selbst initialisierte Objekte in deinen eigenen Komponenten auch wieder selbst freigeben; aber in deinem Code ist kein Destructor mit entsprechenden Aufrufen drin... ?  Ich halte das für ein Speicher-Leck. Übrigens nennt man sowas allgemein eine FIFO-Liste (First In First Out), das kann man dann auch als MessageQueue verwenden...
@ase: Du weißt schon, wovon du da so redest, gell?  Bei einem Chat... Aber egal, wenn du in dieser Größenordnung noch QoS sicherstellen willst, würde ich clustern; nur, wenn man mit sowas anfängt, dann sprengt das ruck-zuck die Grenzen dessen, was man als einzelner Mensch noch auf die Kette kriegt.
cu
Narses
|
|
ase 
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Do 27.01.05 09:05
Heyho
Ja also ich glaub der Scorpion hat mich nich richtig verstanden aber ich hab auch Infos unterschlagen
Das ganze ist ein non VCL Projekt.
Und natürlich weiß ich wovon ich rede und Clustern brauch ich definitiv nicht. Der Server ist nur eine 'Gehhilfe' für die Clients. Der Chat selbst soll dann mittels UDP Hole Punshing P2P statt finden. Es soll dann noch Video und Audio Stream mit rein.
Ich habe bereits erste Tests bezüglich der Performance gemacht. Wenn 1.000.000 Clients von 100 Threads verwaltet werden, dann habe ich 10.000 Clients pro Thread, was zu verkraften ist. Diese 10.000 Clients werden dann nochmal in Work Areas aufgeteilt zu je 10 Clients. Somit brauch ich nich immer alle 1.000.000 Clients locken, sondern immer nur 10. Das ganze läuft dann noch über sone Art TMultiReadExclusiveWriteSynchronizer ab. Ich brauch ja eigentlich nur locken, wenn eine Verbindung wegfliegt.
Mein Problem war jetzt folgendes: Wenn also ein Thread 10.000 Clients am Start hat, dann kommen in der Message Queue vom Thread ja permantent WSAAsyncSelect() Messages an. Da bekomme ich als wParam das Socket Handle. Jetzt müsste ich ja meine 10.000 Clients durchsuchen um rauszufinden, welcher von denen zu dem Socket Handle gehört. Darum wollte ich das Socket Handle mit einem 32 Bit Integer Wert verknüpfen, um mir den Index zu merken. Das war meine Frage ob es da eine Möglichkeit gibt. Mit TStringList hat das wenig zu tun ^^
Somit kann man so einen Server komplett Event driven laufen lassen. Der sollte dann nicht sooo große CPU Load erzeugen.
-EN
_________________ -EN
|
|
ScorpionKing
      
Beiträge: 1150
Win XP
|
Verfasst: Do 27.01.05 13:15
ich habe einen tipp für dich! mach das doch so:
du hast einen master-server, an den schreibt dann ein client eine chat-message, diese wird dann von dem master-server an alle "eingeloogten" clients gesendet außer den, der diese geschrieben hat. und das non-vcl stellt auch kein problem dar, mach doch einfach deine eigene Klasse TStringList!
MfG, Scorpion!
_________________ Aus dem Urlaub zurück!
|
|
ase 
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Do 27.01.05 14:35
Hallo
Nunja, das ist leider keine Lösung. Das Chat Nachrichten P2P gehen sollen und nicht über den Server hat ja auch einen Grund. Das ist nämlich eine Kostenfrage zumal ich eh gern dieses UDP Hole Punshing ausprobieren wollen würde. Im Prinzip hat der Server nichts weiter zu tun, als die An- und Abmeldung und die P2P Verbindung zweier Clients herzustellen. Da sollte ein Thread doch mit 10K Clients fertig werden denke ich mal. Ich hab nur Angst, dass irgendwann meine Message Queue vom Thread überladen wird. Ich weiß, dass WinNT die Queue dynamisch vergrößert aber es gibt sicher auch da Grenzen. Bei Win9X lag die wohl bei 96 Messages.
Naja ich werd das schon irgendwie machen
-EN
_________________ -EN
|
|
|