[ Pobierz całość w formacie PDF ]
.14:The WebDemo program atstartup: it fully supportsgraphics and all other Webextensions, as it is based onthe Internet Explorerengine.The program also handles four events of the WebBrowser control.When the downloadoperations start and end, the program updates the text of the status bar and also the drop-down list of the combo box:procedure TForm1.WebBrowser1DownloadBegin(Sender: TObject);beginStatusBar1.Panels[0].Text := Downloading +WebBrowser1.LocationURL + . ;end;procedure TForm1.WebBrowser1DownloadComplete(Sender: TObject);varNewUrl: string;beginStatusBar1.Panels[0].Text := Done ;// add URL to comboboxNewUrl := WebBrowser1.LocationURL;if (NewUrl ) and (ComboURL.Items.IndexOf (NewUrl) 0);untilif strIn = thenifthenContinue // keep goingelseelsebeginbegin// handle the request, if anything arrivedStrCommand := Copy (strIn, 1, Pos (#10#13. #10#13, strIn) -1);Synchronize(Log);Synchronize(AddRecord);// send results backSynchronize(LogFeedback);Stream.Write(strFeedback[1], Length (strFeedback));end;end;end;end;finallyfinallyStream.Free;end;end;end;end;Copyright ©2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c21.qxd 7/2/01 2:36 PM Page 929Delphi Socket Components 929The server reads data from the client and sends the feedback using a TWinSocketStream, acompulsory approach for blocking servers.The thread is kept active, as it can be reused forsubsequent calls, and reads from a buffer until it find a specific separator (in this case, a dotbetween two line separators, exactly as occurs in the SMTP protocol).When the data isreceived, the server does a synchronized call to the AddRecord method, which is similar to thecode of the previous version of the example.WARNINGThis approach is far from perfect, as all database accesses are serialized, but you could solvethe problem by moving the database access component within the thread and adding a Ses-sion object in case of a BDE application.Not all databases like multithreaded access, though,so serializing the calls is not always a bad idea.This is the multithreaded server application.The client program, instead, uses a standardthread class, derived from TThread.The class creates a client server object internally, so thatmultiple threads could spawn multiple socket connections in parallel (something the pro-gram doesn t really use) and receives a table to work on as parameter in the constructor:typetypeprocedureofobjectTLogEvent = procedure(Sender: TObject; LogMsg: String) of object;classTSendThread = class(TThread)privateprivateClientSocket: TClientSocket;FTable: TTable;FOnLog: TLogEvent;FLogMsg: String;procedure SetOnLog(const Value: TLogEvent);procedureprotectedprotectedprocedure Execute; override;procedureprocedure DoLog;procedurepublicpublicconstructor Create(ATable: TTable);constructorproperty OnLog: TLogEvent read FOnLog write SetOnLog;propertyreadwriteend;endOn the client side, the finite-state machine logic (send, set the wait flag, receive anotherevent, disable the flag, get the next record) is now replaced by a continual and more logicalflow of operations, all part of the Execute method of the thread.You need to add some codeto let the program wait until the server sends a reply.Again, the blocking socket of the clientis not used directly but via a TWinSocketStream object:procedure TSendThread.Execute;procedurevarvarI: Integer;Data: TStringList;Copyright ©2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c21.qxd 7/2/01 2:36 PM Page 930930 Chapter 21 " Internet Programming: Sockets and Indy ComponentsStream: TWinSocketStream;Buf: String;beginbegintrytryData := TStringList.Create;nilClientSocket := TClientSocket.Create (nil);nilStream := nil;trytryClientSocket.Address := EditServer.Text;ClientSocket.ClientType := ctBlocking;ClientSocket.Port := 51;ClientSocket.Active := True;Stream := TWinSocketStream.Create(ClientSocket.Socket, 30000);FTable.First;while not FTable.Eof dowhilenotdobeginbegin// if the record is still not loggedif FTable.FieldByName( CompID ).IsNull oriforthen(FTable.FieldByName( CompID ).AsInteger = 0) thenbeginbeginFLogMsg := Sending + Table.FieldByName( Company ).AsString;Synchronize(DoLog);Data.Clear;// create strings with structure FieldName=Valuefor I := 0 to FTable.FieldCount - 1 dofordoData.Values [FTable.Fields[I].FieldName] :=FTable.Fields [I].AsString;// send the record followed by separatorBuf := Data.Text + #10#13. #10#13;ClientSocket.Socket.SendText(Buf);// wait for reponseif Stream.WaitForData(30000) thenifthenbeginbeginFTable.Edit;SetLength(Buf, 256);SetLength(Buf, Stream.Read(Buf[1], Length(Buf)));FTable.FieldByName( CompID ).AsString := Buf;FTable.Post;FLogMsg := FTable.FieldByName( Company ).AsString + logged as + FTable.FieldByName( CompID ).AsString;endendelseelseFlogMsg := No response for +FTable.FieldByName( Company ).AsString;Synchronize(DoLog);end;endCopyright ©2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c21.qxd 7/2/01 2:36 PM Page 931Internet Protocols 931FTable.Next;end;end;finallyfinallyClientSocket.Active := False;ClientSocket.Free;Stream.Free;Data.Free;end;end;exceptexcept// trap exceptionsend;end;end;end;The thread also has an event handler to let the forms using it define the effect of the OnLogoperation, in the synchronized DoLog method.Finally, this is how the thread starts, when theuser clicks a button in the form:procedure TForm1.Button2Click(Sender: TObject);procedurevarvarSendThread: TSendThread;beginbeginSendThread := TSendThread.Create(Table1);SendThread.OnLog := OnLog;SendThread.Resume;end;endInternet ProtocolsAfter discussing the low-level socket components, we are ready to delve into the core topic ofthis chapter, the use of higher-level Internet protocols.As already mentioned, Delphi 6 now ships with a collection of open-source Internet com-ponents called Internet Direct, or Indy for short.The Indy components, previously calledWinShoes (a pun on the term WinSockets), are built by a group of developers led by ChadHower and are available also in Kylix.You can find more information and possibly updatedversions of the actual components at www.nevrona.com/indy.The Indy components are available within the Delphi IDE, but they are not the only set ofInternet components.Delphi 6 Component Palette also has another page of Internet proto-col components, the FastNet page.These are available for compatibility with Delphi 5 andearlier versions
[ Pobierz całość w formacie PDF ]