| Autor |
Beitrag |
DataCool
      
Beiträge: 112
|
Verfasst: Di 29.04.03 20:42
Hi,
ich habe einen Chat entwickelt, der von verschieden Usern Text empfängt ! Der Empfang wird über die Indy IdTcpServer-Komponente realisieren.
Die Texte der anderen User werden über ein php-Script auf einem Server geschickt !
Jetzt mein Problem :
Im normalen Betrieb läuft als super ! Wenn aber viele User(>2) Ihre Nachrichten sehr schnell hintereinander schicken
werden manche Threads/Connections nicht beendet, die Connwctions schaukeln sich hoch und danach hängt die Anwendung(Keine Rückmeldung)
Zu erwähnen ist vielleicht auch noch, das die Methoden die ich im Ereignis OnExecute des Server nicht 100% thread sicher sind. Wüßte auch nicht wie ich das 100% sicher machen könnte ???
Denn wenn ich eine Nachricht eines Users erhalte, schreibe ich diese im HTML-Format in einen lokalen HTML-File und rufe diesen mit TWebbrowser auf *g
Das Schreiben in den File löse ich mit einer Critical-Section !
Recht komplex u. kompliziert, aber ich hoffe jemand kann mir einen Denkanstoss geben.
Danke, Data
_________________ DataCool
|
|
ase
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Di 06.05.03 14:21
servus
also im allgemainen ist zu sagen: OnExcecute MUSS thread sicher sein.
machs doch so das du mit GetTmpFileName eine tempöräre datei erzeugst. dann kannst du deine CrtiticalSection weg lassen da jeder thread sein eigenes tempfile hat.
besser ist aber das ganze ohne temp files zu lösen:
Quelltext 1:
| WebBrowser1.Navigate('about:XXX'); |
wobei XXX dann der html code ist. also in deinem falle die chat nachricht vom client.
viel spaß!
ase
|
|
DataCool 
      
Beiträge: 112
|
Verfasst: Di 06.05.03 14:57
Hey,
super !
Hätte ich das mit .navigate('about: früher gewusst
Hätte mir viel Arbeit erspart !
Jetzt habe ich das ganze zum laufen bekommen, aber mit Deiner Hilfe kann ich jetzt ne ganze menge optimieren
Danke,
Data
_________________ DataCool
|
|
ase
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Di 06.05.03 15:42
|
|
DataCool 
      
Beiträge: 112
|
Verfasst: Di 06.05.03 15:55
ZU früh gereut *g
Die SAche funktioniert zwar wunderbar und mege schnell, aber jetzt kommt der Hacken :
TWebBrowser aktzeptiert als URL einen Widestring eigentlich sollte der eine Variable größe akzeptieren, aber wenn der text Länger als 512 Zeichen ist tut sich gar nichts mehr
Zu Problem ne Idee ?
Data
_________________ DataCool
|
|
ase
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Di 06.05.03 18:23
servus
nu klor hamma da ne idee.
dein webbrowser hat ne eigenschaft die sich da Document nennt. das ist deine rettung. schau halt:
Quelltext 1:
| (WebBrowser1.Document as IHTMLDocument2).Write{Ln} |
ich schätze das geht nicht bei jeder version vom internet explörer. IHTMLDocument2 geht hoch bis IHTMLDocument5. denke das das dann auch die version des IE sein muss die installiert sein sollte. ist aber nur ne vermutung. wenn du hässliche abstürze vermeiden willst, dann mach erst nen check:
Quelltext 1: 2:
| If not Supports(WebBrowser1.Document, IHTMLDocument2) then ShowMessage('Geht nich!'); |
du musst die unit MSHTML einbinden.
ase
|
|
DataCool 
      
Beiträge: 112
|
Verfasst: Di 06.05.03 20:48
Hi,
irgentwie komm ich mit Deinem Bsp. nicht klat !
Den Html-Code den ich aufrufen möchte steht in einer StringList Eigenschaft Text !
Quelltext 1: 2:
| if supports(WebChat.Document, IHTMLDocument2) then (WebChat.Document as IHTMLDocument2).Write(strLChat.text); |
Bei dem Code bekomm ich die Fehlermeldung : "Es gibt keine überladene Version von supports die man mit Argumenten aufrufen kann"
Ohne die IF-Abfrage kommt die Fehlermeldung : "Inkompatible Typen String und PSafeArray"
Kannst Du da auch weiterhelfen ?
Data
_________________ DataCool
|
|
ase
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Mi 07.05.03 01:23
servus!
also so wie du es in deinem post geschrieben hast geht das nicht. der parameter der funktion write ist ein PSafeArray. Das ist mit nem String nicht zu vergleichern.
Ich habe dir per ICQ nen link geschickt. da findest du ne rar. alles weitere steht beim link.
ich hab die halbe nacht an dem problem gesessen und rausgekommen ist ne hilfsklasse die deine probleme weitestgehend lösen sollte. wenn nich, dann nochma nen post hier absetzen.
wenn das ganze noch jemand anders haben will, dann kann ich die unit hier auch gern posten. ist nicht besonders groß. weiß net ob das gestattet ist.
nu geh ich aber erstmal int bett... :eyes:
cya
|
|
DataCool 
      
Beiträge: 112
|
Verfasst: Mi 07.05.03 10:11
Hi,
habe bis jetzt noch keinen LInk per ICQ bekommen !
Aber poste die Unit doch hier, ich schätze das interessiert auch noch ein paar andere !
Trotzdem schonmal danke für Deine Mühen.
Gruß Jan
_________________ DataCool
|
|
ase
      
Beiträge: 203
Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
|
Verfasst: Mi 07.05.03 10:21
nun gut, wenn du meinst...
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230:
| Unit WebHelper;
{ Unit: WebHelper
Developer: ase, nsX-gteX
Compiler: Delphi, v7.0 Build 4453
Date: 07.05.2003 19:00 --> 08.05.2003 00:15
Classes: TWebHelper -> This class provides capabilities to add HTML text to a TWebBrowser component without creating temprary files or stuff.
Usage: See implementation part.
Comments: Have fun with it!
License: No license. Use it or leave it. My name in your copyright is not required. A copy of your program would be nice but although, is not required. }
Interface
Uses Classes, ComObj, MSHTML, SHDocVw, Variants, SyncObjs;
Type TWebHelper = Class;
TWebHelper = Class(TInterfacedObject) Private FBrowser: TWebBrowser; FIsReady: WordBool; FClear: WordBool; FSave: TCriticalSection; FLineBreak: WordBool;
Function Get_CanPost: WordBool; Protected Procedure Event_DocumentComplete(Sender: TObject; Const pDisp: IDispatch; Var URL: OleVariant); Public Constructor Create(ABrowser: TWebBrowser); Destructor Destroy; Override;
Procedure LoadFromStrings(AStrings: TStrings); Procedure WriteOneString(Const Msg: WideString);
Property WebBrowser: TWebBrowser read FBrowser; Property CanPost: WordBool read Get_CanPost; Property ClearBeforePost: WordBool read FClear write FClear; Property LineBreak: WordBool read FLineBreak write FLineBreak; End;
Implementation
Uses SysUtils, ActiveX;
ResourceString sLineBreakStr = '<br>'; sNotReady = 'Cannot display HTML code yet. Control not initialized.'; sAboutBlank = 'about:blank';
{ TWebHelper - Usage
Property WebBrowser: Read-Only. Returns the TWebBrowser component, TWebHelper actually controlls. You specify this control in the constructor of TWebHelper.
Property CanPost: TWebHelper needs to initialize the TWebBrowser control. This initialization step is done ASYNCHRONOUSLY by the control itself. If done, the control will notify TWebHelper and from there you will be able to post data. If you try to post data wheater TWebHelper is not ready, an exception is raised. The property getter is thread safe.
Property ClearBeforePost: Determined if TWebHelper should clear the browser control before adding new data. If FALSE, the new data is simply added to the browser control.
Property LineBreak: If TRUE, TWebHelper will add a <br> (sLineBreakStr) to every post.
Procedure LoadFromStrings(AStrings: TStrings) This method will add the strings in AStrings to the browser control. If CanPost is FALSE, an exception is raised. Always encapsulate this call in a Try..Except block! The method does _not_ handle exceptions. The AStrings parameter will be handled as read-only an will not be changed.
Procedure WriteOneString(Const Msg: WideString) With that nice trick you can add a single line to the Browser control. Usefull for administrator messages. If CanPost is FALSE, an exception is raised. Always encapsulate this call in a Try..Except block! The method does _not_ handle exceptions. }
Constructor TWebHelper.Create(ABrowser: TWebBrowser); Var v: OleVariant; Begin Inherited Create; // private initialization... FIsReady := False; FSave := TCriticalSection.Create; FClear := False; FLineBreak := True;
// Init the browser. We need to do this step to prevent the browser from // setting FBrowser.Document to NIL. We need the document property. The browser // will initialize it only if he has a valid document. 'ABOUT:BLANK' is valid. // Search www.msdn.micro$oft.com for more details.
FBrowser := ABrowser; FBrowser.OnDocumentComplete := Event_DocumentComplete; v := sAboutBlank; FBrowser.Navigate2(v); End;
Procedure TWebHelper.Event_DocumentComplete(Sender: TObject; Const pDisp: IDispatch; Var URL: OleVariant); Begin // Browser calls us that he has finished his initialization. Fine! Try FSave.Enter;
FIsReady := True; Finally FSave.Leave; End; End;
Procedure TWebHelper.WriteOneString(Const Msg: WideString); Var Doc: IHTMLDocument2; v: OleVariant; Begin // Are we ready? If not CanPost then Raise Exception.Create(sNotReady);
Try // Get the Document interface. OleCheck(FBrowser.DefaultInterface.Document.QueryInterface(IHTMLDocument2, Doc));
// Do we have to clear the page? If FClear then Doc.close;
// Create the array with only one element. Attention: varOleStr does not work. // Only God knows why because it should: MSDN. v := VarArrayCreate([0, 0], varVariant);
If FLineBreak then v[0] := Msg + sLineBreakStr Else v[0] := Msg;
// Send the data to the browser. Doc.write(PSafeArray(TVarData(v).VArray)); Finally // clear the array and release the document. v := Unassigned; Doc := Nil; End; End;
Function TWebHelper.Get_CanPost: WordBool; Begin Try // Thread save. FSave.Enter;
Result := FIsReady; Finally FSave.Leave; End; End;
Procedure TWebHelper.LoadFromStrings(AStrings: TStrings); Var Doc: IHTMLDocument2; v: OleVariant; i: Integer; Begin // Are we ready? If not CanPost then Raise Exception.Create(sNotReady);
Try // Get document interface OleCheck(FBrowser.DefaultInterface.Document.QueryInterface(IHTMLDocument2, Doc));
// Clear the window if neccessary. If FClear then Doc.close;
// Create the array and copy the string list into it. v := VarArrayCreate([0, AStrings.Count - 1], varVariant);
For i := 0 to AStrings.Count - 1 do If (i = AStrings.Count - 1) and FLineBreak then v[i] := AStrings[i] + sLineBreakStr Else v[i] := AStrings[i];
// Send the data. Doc.write(PSafeArray(TVarData(v).VArray)); Finally // free the array and release the interface pointer. v := Unassigned; Doc := Nil; End; End;
Destructor TWebHelper.Destroy; Begin // we do _NOT_ free the browser. this is the VCL's job guy! FBrowser := Nil; // But the CS is ours... FSave.Free; Inherited Destroy; End;
End.
// GREETZ! |
hatte noch nen beispielprogramm geschrieben. kann ja bei fragen daraus auch noch ausschnitte posten.
ich hab die icq nummer aus deinen user details hier im forum genommen. Der User den ich da gefunden hab der heißt auch DataCool. komich...
ase
|
|
|