One of the big DataSnap enhancements in Delphi 6 is the TSOAPConnection component from the Web Services tab of the component palette. The TSOAPConnection can be used for DataSnap applications, provided the DataSnap server is set up to act as a Web service (and is using a SOAP Server Data Module instead of a regular remote Data Module).
The SOAP Connection is a bit similar to the Web Connection because both use HTTP as the transport protocol. The difference is that the SOAP Connection component is used to connect to a Web server application (using HTTP) that implements the IAppServer interface as a Web service. Using a specific URL, we must specify the path info of the THTTPSoapDispatcher on the application server.
SOAP is the protocol that underlies Delphi's support for Web Service applications. SOAP marshals method calls using an XML encoding, whereas SOAP connections use HTTP as a transport protocol. SOAP connections have the advantage that they work in cross-platform applications because they are supported on both Windows and Linux. Because SOAP connections use HTTP, they have the same advantages as Web connections: HTTP provides a lowest -common denominator that you know is available on all clients, and clients can communicate with an application server that is protected by a firewall. As with HTTP connections, you can't use callbacks via SOAP. SOAP connections also limit you to a single remote data module in the application server.
When using SOAP as communication protocol, we cannot just use a regular Windows application as DataSnap server. Instead, we must explicitly make sure to use a Web server application (one that exposes the IAppServer interface).
We must use the URL property of the SOAPConnection component to point to the THTTPSoapDispatcher component inside the DataSnap server application. For example, URL could be of the form:
http://localhost/cgi-bin/DataSnapServer.exe/SOAP
For more information about SOAP and Web Services please read Chapter 19, "SOAP and Web Services with BizSnap."
For multitier applications in C++Builder 6 (on Windows) to connect to Kylix 3 (on Linux), the communication has to be based on SOAPthe only communication protocol both C++Builder and Kylix have in common. This means we have a SOAP (remote) Data Module and TDataSetProvider component on the server side, and a TSOAPConnection component on the client side. In the remainder of this chapter, I will show the steps to build a Soap Server and Client using C++Builder 6 Enterprise (the steps are similar for Kylix 3 for C++).
Let's start by building a SOAP DataSnap CGI executable Server in C++Builder 6 Enterprise, which consists of the following steps:
Start C++Builder 6 Enterprise and close the default project (if any).
Click File, NewOther, and go to the WebServices tab of the Object Repository.
Double-click the SOAP Server Application icon, which gives the New Soap Server Application dialog.
Select CGI executable and click the OK button. A new Soap Server Application has now been generated for you.
Answer No to the question Create Interface for SOAP module.
The Soap Web Module contains three automatically generated components : THTTPSoapDispatcher , THTTPSoapCppInvoker , and TWSDLHTMLPublish . See Chapter 19 for more information about these components.
Save the Soap Web Module in file SWebMod.cpp and the project in file SoapServer42.bpr .
Now, click File, NewOther, and go back to the WebServices tab of the Object Repository.
This time, double-click the SOAP Data Module icon, which results in the Soap Data Module Wizard.
Enter SoapDataMod42 as Class Name (see Figure 21.7), and click the OK button. A new Soap Data Module has now been generated for you.
Save this new unit with the Soap Data Module as SDataMod.cpp .
Drop a TClientDataSet component on the Soap Data Module; set its Name property to cdsBiolife . Set its FileName property to biolife.xml . (The biolife.xml table can be found in the C:\Program Files\Common Files\Borland Shared\Data directory.)
Drop a TDataSetProvider component on the Soap Data Module, set its Name property to dspBiolife , and its DataSet property to cdsBiolife (see Figure 21.8).
Click the Soap Data Module, go to the Events tab of the Object Inspector, and write the following code in the OnCreate event handler of the Soap Data Module:
void __fastcall TSoapDataMod42::SoapDataModuleCreate(TObject *Sender) { cdsBiolife->Open(); }
This will make sure that the cdsBiolife TClientDataSet is opened when the SOAP Data Module is created. As an alternative you can set the Active property of the cdsBiolife TClientDataSet to true at design time, which will load the entire contents of the biolife.xml file in cdsBiolife (also leading to a bigger SDataMod.dfm file).
Compile and deploy your SoapServer42 application in the cgi-bin or scripts directory of your Web server. Make sure to remember the URL. If the Web server is installed on your local machine, this can be something like http://localhost/cgi-bin/SoapServer42.exe.
You can test the output in a browser using the /wsdl switch. You're set if you see the interfaces IWSDLPublish , IAppServer , and IAppServerSOAP , as well as ISoapDataMod42 , as can be seen in Figure 21.9.
Note that for real-world deployment you probably want to ensure that you compile the SOAP Server without the dynamic RTL and runtime packages, so you only have to deploy the executable together with the MIDAS.dll and Borlndmm.dll (which is easier than having to deploy all packages too). See Chapter 19 for more information on SOAP and Web Services.
Now that we have a SOAP DataSnap CGI executable Server written in C++Builder 6 Enterprise, we can start writing the Soap DataSnap Client written in C++Builder 6 Enterprise, using the following steps:
Start C++Builder 6 Enterprise, and start the project type that you want (anything works). I will assume that we use a regular Windows client, so do File, NewApplication.
Save Unit1.cpp as ClientForm.cpp , and the project in file SoapClient.bpr .
Drop a TSoapConnection component from the Web Services tab of the C++Builder 6 Enterprise Component Palette.
Set the URL property of the TSoapConnection component to http://localhost/cgi-bin/ (where server is the name or IP address of your SOAP server machine). Followed by the name of the SOAP Server application ( SoapServer42.exe ), then followed by /soap , and the interface name of your SOAP Data Module ( /ISoapDataMod42 ) resulting in http://localhost/cgi-bin/SoapServer42.exe/soap/ISoapDataMod42 .
Drop a TClientDataSet component, and set its RemoteServer property to the TSoapConnection component.
Now, open the ProviderName property, which will list dspBiolife (as exported from the SOAP Data Module). If at this time you do not see the name of the exported TDataSetProvider , you have to go two steps back and see if you made a mistake in the value for the URL property (you might want to try to replace ISoapDataMod42 with IAppServerSoap ).
Drop a TDataSource component and set its DataSet property to the TClientDataSet component.
Drop a TDBGrid component and set its DataSource property to the TDataSource component.
Drop a TDBNavigator component and set its DataSource property to the TDataSource component, too.
Drop a TDBImage component, set its DataSource property to the TDataSource component, and its DataField property to 'Graphic' . Note that it might take a few seconds for the combo box of the DataField property to drop down because of the fact that the TClientDataSet has to request the meta data (to obtain the field names ) from the SOAP Server.
Now, finally, set the Active property of the TClientDataSet component to true to get live data at design time, as can be seen in Figure 21.10.
Again, if you want to make modifications to the client application and send these back to the server, you need to call the ApplyUpdates methods (see Chapter 20 regarding the DataSnap for more details on this).
A final word on performance issues: Please note that it might take a while before you get a response when you first click any of the two buttons . The delay is caused by the fact that a SOAP request has to be put in a SOAP envelope and sent over the Internet to the Web service (using HTTP). At the server machine, the Web server CGI executable has to be started. Then, it must unpack the SOAP envelope, dispatch the SOAP request, execute the C++ method, pack the result back in a SOAP envelope again, send it back to the Web service consumer (again over the Internet using HTTP), and then exit the Web service CGI executable again. A more efficient approach for real-world Web services will certainly be to deploy them as ISAPI/NSAPI DLLs or Apache DSO modules.
Top |