Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi







Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (0)


An Application Loader with a TCPServerGo to Max Kleiner's websiteComponent available for this articleFormat this article printer-friendly!Bookmark function is only available for registered users!
How to build DelphiWebStart (DWS) ?
Product:
Delphi 5.x (or higher)
Category:
NetCLX
Skill Level:
Scoring:
Last Update:
12/30/2007
Search Keys:
delphi delphi3000 article borland vcl code-snippet indy dws tcp tcp-loader thread deploy sourceforge delphiwebstart application-loader ssl openssl
Times Scored:
8
Visits:
8847
Uploader: Max Kleiner
Company: kleiner kommunikation
Reference: http://sourceforge.net/projects/delphiwebstart
Component Download: http://max.kleiner.com/download/dws.zip
 
Question/Problem/Abstract:
DelphiWebStart (DWS) is an Application Loader with TCP Sockets based on a SmallClient which is first spread over the Web, VPN or Intranet. Then a user can download data (exes, maps, files etc.) from a easy list and start it. DWS 1.8 supports OpenSSL.
  
Answer:



Major changes between DWS 1.8 and DWS 1.9:

      o Now OpenSSL 0.9.8g support
      o Several compilation issues fixed
      o Compilation switch between Indy 9 and 10
      o Added support for hash ckecking MD5 of the OpenSSL Lib
      o Built in mutex check for single instance of DWS Server
      o Various example of certificate files included (3 files)
      o Rework of the app loader list with an open file dialog
      o Docu of install und use with Delphi 7.1 / Indy support
      o Fix loading and start file names with space
      o Industrialized use of exceptions / debug mode
      o Reworked parts of the ip_a.ini file
      o Extended message passing back to DWS Server

17.12.2007 DWS 1.9
10.11.2007 DWS 1.8
21.11.2005 DWS 1.5 and deployment now available:
since 28.10.2003 Project DWS is under Sourceforge:


http://sourceforge.net/projects/delphiwebstart
***********************************************
- new package with executables (win32) and qtint70.dll
- recompile without change finder also on CLX and Linux
- source improvments
- uml diagrams, tooltip descriptions
- load&store definition files
- change finder and copy checking
- better client disconnecting, monitor as shortmessages


We had the requirement starting different Delphi apps from a
linux or windows server, wherever you are.
We call it Delphi Web Start (DWS).
The dws-client gets a list and after clicking on it, the app is
loading from server to client with just a stream.
First we had to choose between a ftp and a tcp solution. The
advantage of tcp is the freedom to define a separate port, which
was "services, port 9010 - DelphiWebStart".  
You will need indy. Because it is simple to use and very fast.
The tcp-server comes from indy which has one great advantage:

CommandHandlers is a collection of text commands that will be
processed by the server. This property greatly simplify the
process of building servers based on text protocols.

First we start with DWS_Server,
so we define two command handlers:

CTR_LIST = 'return_list';
CTR_FILE = 'return_file';

By starting the tcp-server it returns with the first command

handler "CTR_LIST" a list of the apps:


procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
...
// comes with writeline from client
if sRequest = CTR_LIST then begin
  for idx:= 0 to meData.Lines.Count - 1 do
  athread.Connection.WriteLn(ExtractFileName(meData.Lines[idx]));
  aThread.Connection.WriteLn('::END::');
  aThread.Connection.Disconnect;


One word concerning the thread:
In the internal architecture there are 2 threads categories.

First is a listener thread that "listen" and waits for a
connection. So we don't have to worry about threads, the built in
thread will be served by indy though parameter:

IdTCPServer1Execute(AThread: TIdPeerThread)

When our dws-client is connected, this thread transfer all the
communication operations to another thread.
This technique is very efficient because your client application
will be able to connect any time, even if there are many
different connections to the server.


The second command "CTR_FILE" transfers the app to the client:
if Pos(CTR_FILE, sRequest) > 0 then begin
    iPos := Pos(CTR_FILE, sRequest);
    FileName := GetFullPath(FileName);

    if FileExists(FileName) then begin
      lbStatus.Items.Insert(0, Format('%-20s %s',
        [DateTimeToStr(now), 'Transfer starts ...']));
     FileStream := TFileStream.Create(FileName, fmOpenRead +      

fmShareDenyNone);
     aThread.Connection.OpenWriteBuffer;
     aThread.Connection.WriteStream(FileStream);
     aThread.Connection.CloseWriteBuffer;
     FreeAndNil(FileStream);
     aThread.Connection.Disconnect;


Now let's have a look at the client side. The client connects to
the server, using the connect method of TIdTcpClient. In this
moment, the client sends any command to the server, in our case
(you remember DelphiWebStart) he gets the list of available apps:

    with IdTCPClient1 do begin
      if Connected then DisConnect;
      showStatus;
      Host:= edHost.Text;
      Port:= StrToInt(edPort.Text);
      Connect;
      WriteLn(CTR_LIST);

After clicking on his choice, the app will be served:

with IdTCPClient1 do begin
ExtractFileName(lbres.Items[lbres.ItemIndex])]));
WriteLn(CTR_FILE + lbres.Items[lbres.ItemIndex]);
FileName:= ExpandFileName(edPath.Text + '/' +
ExtractFileName(lbres.Items[lbres.ItemIndex]));
...
FileStream := TFileStream.Create(FileName, fmCreate);
   while connected do begin
     ReadStream(FileStream, -1, true);
   ....
   execv(pchar(filename),NIL);

Better with a compiler directive to load delivered files:
     {$IFDEF LINUX}
        execv(pchar(filename),NIL);
      //libc.system(pchar(filename));
     {$ENDIF}
     {$IFDEF MSWINDOWS}
     // shellapi.WinExec('c:\testcua.bat', SW_SHOW);
     with lbstatus.items do begin
       case  shellapi.shellExecute(0,'open', pchar(filename), '',NIL,
                    SW_SHOWNORMAL) of
         0: insert(0, 'out of memory or resources');
         ERROR_BAD_FORMAT: insert(0, 'file is invalid in image');
         ERROR_FILE_NOT_FOUND: insert(0,'file was not found');
         ERROR_PATH_NOT_FOUND: insert(0,'path was not found');
       end;
       Insert(0, Format('%-20s %s',
               [DateTimeToStr(now), filename + ' Loaded...']));
     end
     {$ENDIF}


The datastructure is a direct file access. In this case, rather than populating a stand-alone memory structure, the data is written to the StringGrid (which is serving both as a memory structure for holding the data and as a visual control for navigating and editing the data).


type
TAppData = record
   Name: string[50];
   Size: longint;
   Release: string[30];
   descript: string[80];
end;

  TBuildAppGrid = class (TObject)
  private
    aGrid: TStringGrid;
    app: TAppData;
    f: file of TAppData;
    FaDatfile: ShortString;
    Fmodified: Boolean;
  protected
    function GetaDatfile: ShortString;
    procedure SetaDatfile(const Value: ShortString);
  public
    constructor initGrid(vGrid: TStringGrid; vFile: shortString);
    procedure fillGrid;
    procedure storeGrid;
    property aDatfile: ShortString read GetaDatfile write SetaDatfile;
    property modified: Boolean read Fmodified write Fmodified;
  end;

One note about execution on linux with libc-commands; there will
be better solutions (execute and wait and so on) and we still
work on it, so I'm curious about comments on

   "Delphi Web Start"

therfore my aim is to publish improvments in a basic framework on
sourceforge.net depends on your feedback ;)

Many thanks to Dr. Karlheinz Mörth with a first glance.
  
Test your server with the telnet program. After connecting with host, type "return_list" and you'll see a first result. I know that we haven't implement an error handling procedure, but for our scope this example is almost sufficient. The DWS-source holds version 1.5 and has the following references:
- VideoOnDemand Loader
- CBT MultipleChoice Trainer
- Map Server







Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment













 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
Hans Gulö
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)