Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
491 Users Online NOW
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



Loremo - the 1.5 liter car coming in 2009




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 (2)


Web Service Workshop with Remote Data StoringGo to Max Kleiner's websiteComponent available for this articleFormat this article printer-friendly!Bookmark function is only available for registered users!
The Borland VCLScanner explained almost Step by Step
Product:
Delphi 6.x (or higher)
Category:
WebSnap
Skill Level:
Scoring:
Last Update:
08/20/2006
Search Keys:
delphi delphi3000 article borland vcl code-snippet web-services remote URL SOAP XML SOA
Times Scored:
5
Visits:
5782
Uploader: Max Kleiner
Company: kleiner kommunikation
Reference: N/A
Component Download: http://max.kleiner.com/download/webservices.zip
 
Question/Problem/Abstract:
How do you transfer scanned client-data with a web service from a client to a database server or a file automatically and store it?
Answer:



Weeks ago I got a source code example called VCLScanner from Borland that scans your harddisk and sends a report to a server like a Remote Procedure Call over the web. My students were fascinated and put me in charge to write an article about the main topics about Web Services and how the source works.
VCL Class Scanner will generate a class usage report based on Delphi and C++Builder applications located on your system and send the report to a http location.

Now I'm going to explain the build an made a few modifications, so you can download and compile the source with Delphi6 and test the Web Service on your local host and your personal web server previously installed.    


What's a Web Service?
----------------------------------------------------------------------------

Delphi’s support for Web Services is designed to work using SOAP (Simple Object Access Protocol). SOAP is a standard lightweight protocol for exchanging information in a decentralized, distributed environment. It uses XML to encode remote procedure calls and typically uses HTTP as a communications protocol.

ObjectPascal’s SOAP-based technology is available on Windows and will later be implemented on Linux, so that it can form the basis of cross-platform distributed applications. There is no special client runtime software to install, as you must have when distributing applications using CORBA.
Because this technology is based on HTTP messages, it has the advantage that it is widely available on a variety of machines.


Build the Server
----------------------------------------------------------------------------

Open please the group-file ProjectWServices.bpg.
Let's have a look first in the server code so you can see the Web Service main methods in the interface IVCLScanner:

type
  IVCLScanner = interface(IInvokable)
  ['{8FFBAA56-B4C2-4A32-924D-B3D3DE2C4EFF}']
    function PostData(const UserData : WideString;
                      const CheckSum: DWORD) : Boolean; stdcall;
    procedure PostUser(const Email, FirstName, LastName:
                        WideString); stdcall;
  end;

We can see (so I hope) the Web Service is able to PostData in a file or to PostUser in a database. Before a Web Service application can use this invokable interface, it must be registered with the invocation registry. On the server, the invocation registry entry allows the invoker component (THTTPSOAPPascalInvoker) to identify an implementation class to use for executing interface calls.
All this goes with the Web Service Wizard so define the interfaces that make up your Web Service is easy (at least).

Note: It is a good idea to create your interface definitions in their own units, separate from the unit that contains the implementation classes. In this way, the unit that defines the interfaces can be included in both the server and client applications.

Now we made our own entries to store data in a file. The only thing you must do is changing the path of the FileName:


function TVCLScanner.PostData(const UserData: WideString; const CheckSum:
                                       DWORD) : Boolean;
var
  SL       : TStringList;
  FileName : String;
begin
  SL := TStringList.Create;
  FileName := 'D:\Franktech\Webservices\'+FormatDateTime('yyyymmdd-
                                     hhnnsszzz',Now)+'.txt';
  SL.Text := UserData;
  SL.SaveToFile(FileName);
  SL.Free;
  Result := True;
end;

The same goes for the database configuration with dbExpress, please have a look at the help about configuring TSQLConnection and compare with the source code.

Update 1: see below how to do it with Delphi 10!

After configuration only one line left customising depending on your InterBase file location and the server name, in my example the same like the client machine (milo2):

  Params.Add('Database=milo2:D:\franktech\webservices\umlbank.gdb');


Compile and copy the Web Service to the Web Server
-----------------------------------------------------------------------------

That's all for the server so we can compile it.
Now comes the more interesting part. You have to copy the VCLScannerServer.exe in your web server's scripts directory, like a CGI-script or an NSAPI-DLL.
Then you made a double click on the EXE and it will generate a file which goes like this:

-------------------------------------------
VCLSCANNERSERVER_WSDLADMIN.INI

[IWSDLPublish]
IWSDLPublishPort=http:///soap/IWSDLPublish

[IVCLScanner]
IVCLScannerPort=http:///soap/IVCLScanner
-------------------------------------------
  
This comes from the method (from path info soap*)
WSDLHTMLPublish1.DispatchRequest(Sender, Request, Response);
and we need this data to customize the client.

The whole WSDL publisher publishes a WSDL document that describes your interfaces and how to call them. It enables clients that are not written using Delphi to call on your Web Service application.
In our case (Delphi to Delphi on a local machine) we only need to fill the URL info path in our client main.pas.


Build the Client
----------------------------------------------------------------------------

Note: On client apps, an invocation registry entry allows components to look up information that identifies the invokable interface and supplies information on how to call it.

Next, we provide the THTTPRio object with the information it needs to identify the server interface and locate the server. All you need to do is supply the URL where you install the Web Service app.

However, you may want to make your Web Service available to a wider range of clients. E.G., you may have clients that are not written in Delphi. If you are deploying several versions of your server app, you may not want to use a single hard-coded URL for the server, but rather let the client look up the server location dynamically. For these cases, you may want to publish a WSDL document that describes the types and interfaces in your Web Service, with information on how to call them.
But in our case we only change the component THTTPRIO the URL property:

http://milo2/scripts/VCLScannerServer.exe/soap/IVCLScanner
//(milo2 or localhost is the web server)

As I said, if the server is written in Delphi, the identification of the interface on the server is handled automatically, based on the URI that is generated for it when the interface is registered.  
Note: The path portion of this URL should match the path of the dispatcher component in the server’s Web Module, that's why the information of the generated file is so important.

For testing and time saving you can change line 310
   FindFiles(dlbDirectory.Directory,Aborted);
with a hard-coded file to scan like:
   FindFiles('D:\franktech\entwickl\comdll_intf',aborted);

The client calls the web service trough an interface object:  
  try
   WS := HTTPRIO1 as IVCLScanner;
   WS.PostData(reFinalResults.Text,CRC);
    
Now if all goes well it writes some files on your disk with scanned data in it. When you have trouble with database configuration or running out of time (lost in space) deactivate line 1063:

   WS := HTTPRIO1 as IVCLScanner;
   WS.PostUser(leEmail.Text,leFirstName.Text,leLastName.Text);


Conclusion
-----------------------------------------------------------------------------
To be happy and give some contributions try also the original Borland URL:
   WSDLLocation =
       'http://ww6.borland.com/webservices/VCLScanner/
                         VCLScannerServer.exe/wsdl/IVCLScanner'
  
Hope you'll learn from the example, for further actions here a step be step to build a Web Service Server:

1 Define and implement classes that implement the invokable interfaces you   defined.

2 If your application raises an exception when attempting to execute a SOAP request, the exception will be automatically encoded in a SOAP fault packet, which is returned.

3 Choose File|New|Other, and on the WebServices page, double-click the Soap Server application icon. Choose the type of Web server application you want to have implement your Web Service.

4 The wizard generates a new Web Service application that includes three components:

An invoker component (THTTPSOAPPascalInvoker). The invoker converts between SOAP messages and the methods of any interfaces you registered.
A dispatcher component (THTTPSoapDispatcher). The dispatcher automatically responds to incoming SOAP messages and forwards them to the invoker.
A WSDL publisher (TWSDLHTMLPublisher). The WSDL publisher publishes a WSDL document that describes your interfaces and how to call them.

5 Choose Project|Add To Project, and add the units you created to your Web server application.

Note: All hints about publishing or registering is get done at runtime, so no registry or helper-file is needed but you can use the admin-file to change at runtime ports or adresses (VCLSCANNERSERVER_WSDLADMIN.INI)

Calling the Service from .NET goes like this:
private void Page_Load(object sender, System.EventArgs e)
{
   IVCLScanner.IVCLScannerservice objIVCLScanner = new
   IVCLScanner.IVCLScannerservice();
      bool booScanner = objIVCLScanner.PostData("blabla",413049395);
      lblScanner.Text = "" + booScanner;
}

We're learning from day to day (more at night ;)) so wisdom is where knowledge ends.

--------------------------------------------------------------
Update 1: dynamic dbexpress with Delphi 10

const
StrDatabase2Dfr =
    'Database=APSN21:D:\kleiner2005\ekon9_10\soa_vcl\umlbank2.gdb';
StrInsertSQLStat = 'insert into KINGS values ("%s", "%s", "%s")';


procedure TVCLScanner.PostUser(const Email, FirstName, LastName: WideString);
var
  SQLConnection1: TSQLConnection;
  DataSet: TSQLDataSet;
begin
  //webModule1.SQLConnection1.Open;
  SQLConnection1:= TSQLConnection.Create(NIL);
  with SQLConnection1 do begin
    ConnectionName := 'VCLScanner';
    DriverName := 'INTERBASE';
    //LibraryName := 'dbexpint.dll' in D6;
    LibraryName:= 'dbxint30.dll';
    VendorLib:= 'GDS32.DLL';
    GetDriverFunc:= 'getSQLDriverINTERBASE';
    Params.Add('User_Name=SYSDBA');
    Params.Add('Password=masterkey');
    //Params.Add('Database=myserver:X:\vclscanner.gdb');
    Params.Add(StrDatabase3Dfr);
    LoginPrompt:= False;
    Open;
  end;
  DataSet:= TSQLDataSet.Create(nil);
  with DataSet do begin
    SQLConnection:= SQLConnection1;
    CommandText:= Format(StrInsertSQLStat,
                             [Email,FirstName,LastName]);
    try
      ExecSQL;
    //silent cause of CGI Webscript
    except
    end;
  end;
  SQLConnection1.Close;
  DataSet.Free;
  SQLConnection1.Free;
end;





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
dbExpress
    miri (Apr 9 2002 8:42PM)

So well done, learning by doing is great but I really have some trouble with TSQLConnenction at run time, how do we set the connection, couldn't find an alias in SQL Explorer ?
Respond

RE: dbExpress
Max Kleiner (Apr 10 2002 8:07AM)

just to check dbExpress, put a TSQLConnection on a form then double-click the TSQLConnection to display the Connection Editor and set parameter values (database path, connection name etc.) to indicate the settings.
But in our example, all goes by runtime with dbExpress we don't need an alias or the BDE either.
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
S. Kucherov
 
   














 







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