Home arrow Delphi-Kylix arrow A Real World Client Server Application in Delphi
DELPHI-KYLIX

A Real World Client Server Application in Delphi


The example we used in the previous article is fine, but it can never be a real world application. It is not thread safe, and it does not identify all connected clients clearly enough. In this final part of the series, we will modify the application we have created in the earlier parts so that it can be used in the real world.

Author Info:
By: Leidago
Rating: 5 stars5 stars5 stars5 stars5 stars / 30
December 26, 2006
TABLE OF CONTENTS:
  1. · A Real World Client Server Application in Delphi
  2. · The Client
  3. · The Server
  4. · The Complete Server Code

print this article
SEARCH DEVARTICLES

A Real World Client Server Application in Delphi
(Page 1 of 4 )


A downloadable zip file is available for this article.

So what do we mean by thread safe?

Delphi components by their very nature are not thread safe. It is therefore not advisable to try to access them from a thread-based application. For instance, a TMemo component cannot be referenced directly from an idHTTPServer objects' methods such as Get, Post or Command Other; if this is done an exception is generated and the program appears to hang.

We know from our previous discussions that all indy components are thread-based, since indy was designed around threads. So how do we make an application thread safe? Below is an example of code (from our client application) that is not thread safe:

procedureTForm1.Button1Click(Sender: TObject);

begin

 IdTCPClient1.SendCmd(edit1.text);

 memo1.Clear;

 memo1.lines.add(idtcpclient1.Socket.ReadLn);

end; 

We make our application thread safe by using thread safe classes such as the VCL's TThread class that passes information from a secondary thread to the main thread. The main thread in this case is your application.

Windows designates a thread every time you start an application. You can verify this by starting an application, for example notepad.exe, then opening up the task manager (Ctrl+Alt+Del). You will see notepad.exe on the list under processes.

In our client application, we have a tmemo component that we use to display quotes and dates in. This component is owned by the "main" thread, therefore it has direct access to this component. So there is no question of it not being thread safe.

The moment a secondary thread is introduced into this equation, and that secondary thread wants to access components owned by the main thread, you have to find a way to enable that access. Before we move on to discuss how to enable that communication between main and secondary threads, let's define what a secondary thread is. A secondary thread is any thread that runs within the main thread. So in our case, indy components, such as the idTCPServer component, will start secondary threads within our application. 

So any thread that is not the main thread is a secondary thread. Now that we got that out of the way, let's get back to what methods are used to enable the passing of information between the main and secondary threads. The VCL's TThread class contains a method called Synchronize that enables the passing of information between the main and secondary threads. We will use this method when we rewrite our previous example in a moment.

Identifying Connected Clients

Identifying connected clients might not be a big deal in most implementations of a client server application, because each client that connects to a server will have an IP address and that is all that is needed to respond to a client's request. But in other situations you will need an IP address and something else to differentiate between clients. For example, in a chat application scenario you would want to identify clients by their nicknames and not by their IP addresses, because two (or more) clients can connect from the same computer and if you do not have anything else to differentiate between them, the server application is going to send the message to both of them, instead of to just one of them.

So what can we do to remedy this situation? Well, for starters, we know that when a client connects to an indy server, the server spawns a new thread for it, and then services it within its own context. Indy has a class called "Context" that enables us to collect information about a client. What we will do then is derive a new class from the Context class that will hold information about the client for us:

Tclientinfo= class(TIdContext)

        public

            IP: String;

            name: String;

end;

This way whenever a client connects, we will collect this information and use it to identify the client. So let's rewrite our previous example and make it a robust client server application.


blog comments powered by Disqus
DELPHI-KYLIX ARTICLES

- Loading an XML Document into the DOM
- Delphi Wrapper Classes and XML
- Delphi and the DOM
- Delphi and XML
- Internet Access: Client Service
- Finishing the Client for an Internet Access ...
- The Client for an Internet Access Control Ap...
- User Management for an Internet Access Contr...
- Important Procedures for an Internet Access ...
- Server Code for an Internet Access Control A...
- Constructing the Interface for an Internet A...
- Building a Server Application for an Interne...
- Building an Internet Access Control Applicat...
- Client Dataset: Working with Data Packets an...
- Using the Client Dataset in an N-Tiered Appl...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials