![]() |
Indy TCP Problem.
Hallo,
Ich habe mit Indy 9 (ob es richtig ist ka) die "Player" also Listener abgefragt
Delphi-Quellcode:
damit der Server die informationen von jedem try Player:=IntToS(AThread.Connection.Server.MaxConnectionReply.Index); s:='SET ONLINEUSER:ENTRYS:'+Player+''; RunCommand(S); except exit; end; finally If InCom2.Strings[0] = 'GETENTRYS' then begin AThread.Connection.WriteLn('OnlinePlayers,'+Player); { Danach erstellt der CLient zur laufzeit Actor[Player] und und fängt an diese zu Positionieren } end; If InCom2.Strings[0] = 'GETPOSX' then begin S:='GET POSX'+InCom2.Strings[1]; sval:=RunCommand(S); AThread.Connection.WriteLn('POSX,'+sval); end; usw... eizelnen Spieler zum client senden kann. Damit die Spieler sichbar werden können. Und um es dynamisch zu halten habe ich es in der art einer Playlist gemacht, so das 1 Mil Player drauf können also Ohne einschränkungen
Delphi-Quellcode:
Das funktioniert auch alles wunderbar, aber da Indy 9 (bei 10 weiss ich es nochnet) immer Probleme macht von Wegen mit der Meldung "Verbindung wurde erfolgreich geschlossen" obwohl es garnicht verordnet wurde, und ich einen Timmer mit 100ms habe, der dauernt nach playern fragt, pos... usw, könnt ihr euch sicher vorstellen was das für ein Spam ist wenn indy anfäng zu buggen.[ONLINUSER] ENTRYS=2 posx1=20 posy1=133 posz1=-0 posx2=20 posy2=133 posz2=-0 Deshalb habe ich Indy 10 Installiert, ... alles schön und gut aber wie frage ich den Bei Indy 10, wieviel "Spieler" zu dem Server verbunden sind?? Ich habe echt kein plan. Ich freue mich auf jeder antwort!! Love Ya All :P Danu. |
Re: Indy TCP Problem.
Wenn ich recht entsinne so:
Delphi-Quellcode:
var
cList: TList; Count: Integer; begin cList := IdTCPServer.Contexts.LockList; try for Count := 0 to cList.Count -1 do with TIdContext(cList[Count]) do Connection.IOHandler.WriteLn ('...'); finally IdTCPServer.Contexts.UnlockList; end; end; |
Re: Indy TCP Problem.
Okay, ich werds Probieren, kann mir evtl jemand auch sagen warum ich immer diese meldung habe sobald ich was zum server schicke etc ... also die Meldung "Verbindung erfolgreich geschlossen" ... Mich nervt das einwenig.. ich würde ja aufgrund desen lieber versuchen Winsocks zu nutzen aber der gibt Fehlercodes raus womit keiner was anfangen kann ( ich zumindest ). SInd das chikanen oder habe ich einfach nur was falsch gemacht? Also Ich habe aner Komponente nix weiteres ausser Port angaben geändert, brauche ich evtl einen ThreadMgr oder sonstiges um den server ohne ewigen Spam laufen zu lassen
Ich sag mal ist ja nicht gerade toll wenn man ewig schilder weg drückt nur weil indy meint ewig die verbindung zu trennen, vorallem kommt das sehr böse wenn es sich dann noch um ein Spiel handelt. Ich lege einfach mal den Server - OnExecute code bei:
Delphi-Quellcode:
und hier die Client Source zur übertragung von Infos:
procedure TForm1.DBServerExecute(AContext: TIdContext);
Var S:String; Val:Integer; sVal:String; begin if BusyGRP.ItemIndex = 0 then Exit; if AContext.Connection.Connected then begin try InCom.DelimitedText:=AContext.Connection.IOHandler.ReadLn(); finally if InCom.Strings[0] = 'GETEXP' then begin sval:=RunCommand('GET '+InCom.Strings[1]+':'+'gexp'); AContext.Connection.IOHandler.WriteLn('GEXP'+','+sVal); end; if InCom.Strings[0] = 'GETPWD' then begin sval:=RunCommand('GET '+InCom.Strings[1]+':'+'Password'); AContext.Connection.IOHandler.WriteLn('PWD'+','+sVal); end; if InCom.Strings[0] = 'GETHEAL' then begin val:=StrToInt(RunCommand('GET '+InCom.Strings[1]+':'+'aheal')); AContext.Connection.IOHandler.WriteLn('HEAL'+','+IntToStr(Val)); end; if InCom.Strings[0] = 'GETAPNTS' then begin val:=StrToInt(RunCommand('GET '+InCom.Strings[1]+':'+'apnts')); AContext.Connection.IOHandler.WriteLn('APNTS'+','+IntToStr(Val)); end; if InCom.Strings[0] = 'GETSTR' then begin val:=StrToInt(RunCommand('GET '+InCom.Strings[1]+':'+'astr')); AContext.Connection.IOHandler.WriteLn('STR'+','+IntToStr(Val)); end; if InCom.Strings[0] = 'SETAPNTS' then begin S:='SET '+InCom.Strings[1]+':'+'apnts'+':'+InCom.Strings[2]; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clred; usrlog.SelText:=''+InCom.Strings[1]+' '; usrlog.SelText:=''+' hat '+InCom.Strings[2]+' apnts.'+slinebreak; try RunCommand(S); except usrlog.SelAttributes.Color:=clred; usrlog.SelAttributes.Style:=[]; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+' Fehlgeschlagen.'+''+slineBreak; end; end else if InCom.Strings[0] = 'SETSTR' then begin S:='SET '+InCom.Strings[1]+':'+'astr'+':'+InCom.Strings[2]; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clred; usrlog.SelText:=''+InCom.Strings[1]+''; usrlog.SelText:=''+' hat jetzt '+InCom.Strings[2]+' STR.'+slinebreak; try RunCommand(S); except usrlog.SelAttributes.Color:=clred; usrlog.SelAttributes.Style:=[]; usrlog.SelText:=''+'»'+' '; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+' Fehlgeschlagen.'+''+slineBreak; end; end else if InCom.Strings[0] = 'SETHEAL' then begin S:='SET '+InCom.Strings[1]+':'+'aheal'+':'+InCom.Strings[2]; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+'»'+' '; usrlog.SelAttributes.Color:=clred; usrlog.SelText:=''+InCom.Strings[1]+''; usrlog.SelText:=''+' hat jetzt '+InCom.Strings[2]+' Heal.'+slinebreak; try RunCommand(S); except usrlog.SelAttributes.Color:=clred; usrlog.SelAttributes.Style:=[]; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+' Fehlgeschlagen.'+''+slineBreak; end; end else if InCom.Strings[0] = 'SETDEF' then begin S:='SET '+InCom.Strings[1]+':'+'def'+':'+InCom.Strings[2]; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clred; usrlog.SelText:=''+InCom.Strings[1]+''; usrlog.SelText:=''+' hat jetzt '+InCom.Strings[2]+' Def.'+slinebreak; try RunCommand(S); except usrlog.SelAttributes.Color:=clred; usrlog.SelAttributes.Style:=[]; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+' Fehlgeschlagen.'+''+slineBreak; end; end else end; if InCom.Strings[0] = 'SETDMG' then begin S:='SET '+InCom.Strings[1]+':'+'dmg'+':'+InCom.Strings[2]; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clred; usrlog.SelText:=''+InCom.Strings[1]+''; usrlog.SelText:=''+' macht jetzt '+InCom.Strings[2]+' Dmg.'+slinebreak; try RunCommand(S); except usrlog.SelAttributes.Color:=clred; usrlog.SelAttributes.Style:=[]; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+' Fehlgeschlagen.'+''+slineBreak; end; end else if InCom.Strings[0] = 'SETEXP' then begin S:='SET '+InCom.Strings[1]+':'+'gexp'+':'+InCom.Strings[2]; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clred; usrlog.SelText:=''+InCom.Strings[1]+''; usrlog.SelText:=''+' hat jetzt '+InCom.Strings[2]+' Exp von ???.'+slinebreak; try RunCommand(S); except usrlog.SelAttributes.Color:=clred; usrlog.SelAttributes.Style:=[]; usrlog.SelText:=''+'»»'+' '; usrlog.SelAttributes.Color:=clblue; usrlog.SelText:=''+' Fehlgeschlagen.'+''+slineBreak; end; end else end; end;
Delphi-Quellcode:
Edit: ähm ja, ich habe überall in den abfragen das ELSE vergessen, ob das jetzt der grund ist idknow, aber ich kanns mir net vorstellen da Indy sogar bei meinen Messanger Projekt son terz gemacht hat und daher ...
Function GetInfo(Typ:String):Integer;
Var SRV:TStringlist; begin Form1.DBCLient.Address:='localhost'; If not Form1.DBCLient.Active then Form1.DBCLIENT.Active:=true; SRV:=Tstringlist.Create; SRV.Delimiter:=','; try Form1.DBClient.Socket.SendText('GET'+Typ+','+Form1.Username); finally Srv.DelimitedText:=Form1.DBClient.Socket.ReceiveText(); if Srv.Strings[0] = TYP then Result:=StrToInt(Srv.Strings[1]); end; end; Function GetInfoS(Typ:String):String; Var SRV:TStringlist; begin Form1.DBCLient.Address:='localhost'; If not Form1.DBCLient.Active then Form1.DBCLIENT.Active:=true; SRV:=Tstringlist.Create; SRV.Delimiter:=','; try Form1.DBClient.Socket.SendText('GET'+Typ+','+Form1.Username); finally Srv.DelimitedText:=Form1.DBClient.Socket.ReceiveText; if Srv.Strings[0] = TYP then Result:=Srv.Strings[1]; end; end; Procedure ModifyInfo(Typ:String;Points:Integer); overload; begin Form1.DBCLient.Address:='localhost'; If not Form1.DBCLient.Active then Form1.DBCLIENT.Active:=true; Form1.DBClient.Socket.SendText('SET'+TYP+','+Form1.Username+','+IntToStr(Points)); end; Procedure ModifyInfo(Typ:String; Str:String); overload; begin Form1.DBCLient.Address:='localhost'; If not Form1.DBCLient.Active then Form1.DBCLIENT.Active:=true; Form1.DBClient.Socket.SendText('SET'+TYP+','+Form1.Username+','+Str); end; RunCommand(); ist nichts besonderes, mit der Function Simuliere ich nur eine DB im format einer INI datei, SET DATEI&SECTION:IDENT:VALUE (Werte schreiben / setzen) GET DATEI&SECTION:IDENT ...auslesen |
Re: Indy TCP Problem.
Die Exception kommt nur in der IDE. Und die kannst du über die Exceptions-Einstellungen ignorieren lassen.
|
Re: Indy TCP Problem.
Woot? Ich habe auf meinen Test Rechner keine IDE's, die meldung kommt mit oder ohne Debugger.
|
Re: Indy TCP Problem.
"Woot" = "We Own Opposing Team" ;)
Und zur Execption: Ist mir neu. Kenne das nur, dass die in der IDE kommt ... :gruebel: |
Re: Indy TCP Problem.
Wie soll ich den eine meldung ignorieren wenn genau das der fall ist.
Stellt euchmal GuildWars, 2Moons oder sontiges MMOG vor okay? So Stats setzen geht nur (!) wenn eine verbindung steht also alles wird in meiner Proviesorischen DB gespeichert. Wenn keine verbindung besteht kannste drücken bis der arzt kommt die werte werden nicht verändert. siehe hier:
Delphi-Quellcode:
Durch die ewigen Disconnect von indy werden die Punkte asyncron inkl der tollen schielder. Was ich wissen will ist, wie kann ich dafür sorgen das nicht ewig die verbindungen vom clienten zum server getrennt werden.procedure TForm1.PlusStrButtonClick(Sender: TObject); Var SRvVal,SrvSP,Value,Pnt:Integer; begin if StrToint(MUSPnt.Caption) < 1 then Exit; SRvVal:=GetInfo('STR'); Value:=SRvVal+1; try ModiFyInfo('STR',Value); finally ATSTR.Caption:=IntToStr(GetInfo('STR')); SRvSP:=GetInfo('APNTS'); Pnt:= SRvSP -1; try ModiFyInfo('APNTS',Pnt); finally MUSPnt.Caption:=IntToStr(GetInfo('APNTS')); end; end; globerg:=GetInfo('STR')*6; globatk:=GetInfo('STR')*7; globdmg:=RandomRange(globerg,globatk)-globdef; ATKRATE.Caption:='Attack Rate: '+slinebreak+' '+IntToStr(GetInfo('STR')*6)+' ~ '+IntToStr(GetInfo('STR')*7) end; Client |
Re: Indy TCP Problem.
In meinem letzten Projekt hab ich Indy10 verwendet und kann das Problem, was du da schilderst, nicht nachvollziehen.
Ich weiß, dass dir das jetzt auch nicht viel hilft. Aber vielleicht bringts dich auf eine Spur, wo da der Wurm drin sein könnte. :mrgreen: Mach doch vielleicht mal ein leeres Projekt, wo du einfach nur 'ne grundlegende TCP-Verbindung und -Kommunikation umsetzt und versuche da, den Knoten aufzudröseln. :gruebel: |
Re: Indy TCP Problem.
Hi,
also ich nutze Indy 9 und 10 in einigen Projekten und habe Deine Meldung nicht nie bekommen, hilft Dir zwar nicht weiter aber das schonmal vorab als Info. Es liegt nicht an Indy sondern irgentwo in Deinem Code bzw. am Aufbau ! In Deinem Client-Code hast Du mehrere Function die dem Server etwas Senden und auf Antwort warten: - GetInfo, GetInfoS, etc. Werden ^^ diese ^^ nur von Deinem Button Click aufgerufen ? Oder vielleicht sogar noch von einem Timer oder Thread aus ? Ich vermute jetzt nämlich mal ins Blaue das sich die einzelnen functions asyncron in die Quere kommen. zum Server-Code: - Was macht Deinen Server Code(OnExecute), wenn beim ReadLn keine Antwort(TimeOut) erhält ? - Dein UserLog ist eine VCL-Komponente, diese ist NICHT THREAD-SAFE, alle Zugriffe muss syncronisiert geschehen - Dein RunCommand, nutzt eine Ini als Mini-DB ? Also wird in eine Datei geschrieben auch dieses IST NICHT THREAD SAFE Du siehst also es gibt mehrere Stellen die Dein Problem verursachen könnten. Greetz Data |
Re: Indy TCP Problem.
Ich habe 3 CLients und 3 Server, on timer event gibt es nur einen Coordinaten austauch und chat messages zu entfangen, aber beide haben erschiedene Server. Es gibt einen DB Server der nur informationen speichert das heisst Stats , Exp, Name, Login. Der message Server Empfängt messages und leitet sie global weiter, so das sie jeder lesen kann, das konnte ich fixen. bei stats verteillung Liest und Schreibt er gleichzeitig.
Aber deine ahnung trifft zu, bei einen Klick des STR Buttons Werden mehrere informationen Gesendet und angefordert
Delphi-Quellcode:
procedure TForm1.PlusStrButtonClick(Sender: TObject); Var SRvVal,SrvSP,Value,Pnt:Integer; begin if StrToint(MUSPnt.Caption) < 1 then Exit; SRvVal:=GetInfo('STR'); // Anfordern Value:=SRvVal+1; try ModiFyInfo('STR',Value); // setzen finally ATSTR.Caption:=IntToStr(GetInfo('STR')); // Anfordern SRvSP:=GetInfo('APNTS'); // Anfordern Pnt:= SRvSP -1; try ModiFyInfo('APNTS',Pnt);// setzen finally MUSPnt.Caption:=IntToStr(GetInfo('APNTS')); // Anfordern end; end; globerg:=GetInfo('STR')*6; // Anfordern globatk:=GetInfo('STR')*7; // Anfordern globdmg:=RandomRange(globerg,globatk)-globdef; ATKRATE.Caption:='Attack Rate: '+slinebreak+' '+IntToStr(GetInfo('STR')*6)+' ~ '+IntToStr(GetInfo('STR')*7) // Anfordern end; Ich werde mal schaun ob ich das einwenig verringern kann. Beim chat habe ich das "Einfrieren" rausbekommen, der client hat sich einfach imma aufgehangen nach absenden der message, und es lag an try ... abfrage. Aber wie soll ich ein MMOG baun, wenn der Server nach "1" client schon überfordert ist ist konsolen anwendung dafür besser? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz