Autor Beitrag
DataCool
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 203

Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
BeitragVerfasst: 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:

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: Di 06.05.03 14:57 
Hey,

super ! :dance:

Hätte ich das mit .navigate('about: früher gewusst :autsch:
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 :beer:

Danke,

Data

_________________
DataCool
ase
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 203

Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
BeitragVerfasst: Di 06.05.03 15:42 
bitte bitte


ase
DataCool Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: 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 :bawling:

Zu Problem ne Idee ?

Data

_________________
DataCool
ase
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 203

Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
BeitragVerfasst: 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:

ausblenden 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:

ausblenden Quelltext
1:
2:
  If not Supports(WebBrowser1.Document, IHTMLDocument2) then
    ShowMessage('Geht nich!');



du musst die unit MSHTML einbinden.



ase
DataCool Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: 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 !

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 203

Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 203

Gentoo, Windows 9X, ME, 2k, NT, XP
Delphi 7 Prof., PHP 5 (Eclipse 3 SDK)
BeitragVerfasst: Mi 07.05.03 10:21 
nun gut, wenn du meinst...

ausblenden volle Höhe 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:
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