views:

319

answers:

7

I have a Client/Server application written Delphi. Essentially all the application is doing is transferring xml data streams between a server application and connected clients. I am currently using the Indy TIdTCPServer component. But the server side application keeps crashing on some of my installments. And it has been extremely difficult to debug. So I am wondering if there is some "architecture" I should be utilizing which does all the tcp/ip connection management and database connection pooling, allowing me to concentrate on the business logic.

Here are more details:

  • clients must maintain a "persistent" connection. There are times when the server must notify and send data to all connected clients.
  • clients are connecting from laptop computers using wireless aircards. So network "drops" are pretty common.
  • Backend database is SqlServer.
  • There can be upward of 100 computers simultaneously connected at a time. When the server gets a new connection (TCPServer.OnConnect) I instantiate my own object containing it own SqlServer database connection. When tcp connections are dropped I in turn free these objects (and associated database connection).
  • Client application have a TTimer built into them. They routinely send heartbeats to the server. And if they "drop"/"lose" their connection they automatically establish a new connection once the network is back.

Anyone have any suggestions on the best approach/architecture here?
I presume the Indy component would work, but at the same time feel I am "reinventing the wheel" with respect to managing the connections.

+5  A: 

Three component sets I am aware of that will take care of the nitty gritty technical aspects of client server applications for you:

You may have to rework your applications to take advantage of the way these component sets work, but assuming you have properly separated layers that shouldn't be too much of a hassle and will buy you the advantage of well tested and widely used code for your client server work.

Marjan Venema
+1. I have evaluated RemObjects and kbmMW and they are EXCELLENT. I have not evaluated Asta but it looks promising.
Warren P
Asta probably isn't the best option, as it's not actively developed any more.
Daniel Maurić
@dmauric.mp: thanks, didn't know that. Looking at the site again it does look pretty outdated: mentioning Asta 3.0 with support for Delphi up to version 7 and a main page last update 28 jan 2006...
Marjan Venema
Checkout out RemObjects now. Having some difficulties installing the various kbmMW packages.
M Schenkel
+1  A: 

If you want some light TCP/IP components, take a look at our SynCrtSock unit.

You'll find low-level classes to create IP Client and Servers. We implemented both TCP/IP and UDP/IP in one of our applications.

There is also a THttpServer class, which implement a HTTP/1.1 server. Therefore it follows the HTTP/1.1 connection management. There is also an optional compression, and using HTTP/1.1 on a port other than 80 is not a bad idea. And what is good with HTTP/1.1 is that it can pass through firewalls, and can be easily be VPNed or hosted on another HTTP server (like IIS or Apache) with a proxy. There is even a FastCGI class, if you need such a server under a linux-based solution. Of course, a THttpClientSocket class does the same on the client class.

We use these classes to add HTTP/1.1 connection to our Open Source SQLite3 RESTful framework - http://synopse.info/forum/viewforum.php?id=2

See http://synopse.info/fossil/artifact?name=722e896e3d7aad1fe217b0e2e7903483e66d66d1 for the SynCrtSock unit. Open source, work from Delphi 7 to Delphi 2010.

A.Bouchez
Does HTTP automatically assume "Stateless" in the sense the client makes the connection and request, server responds with data, and client disconnects? This particular application needs to maintain a persistent connection.
M Schenkel
HTTP/1.1 defines a persistent connection. In our implementation, we set a "KeepAliveMS" property (client-side), to maintain the connection during the supplied milliseconds specified value. It's stateless from the server point of view, but the connection is not broken. With such persistent connections, I've seen x10 up to x40 speed enhancements under Windows. You can use cookies in order to provide a session feature. But since we wanted to implement a RESTful framework, we didn't use cookies, but a pure stateless framework.
A.Bouchez
+1  A: 

Misha Charrett's CSI Application Framework covers pretty much exactly what you're asking for.

It's an open source Delphi framework that at its heart is a distributed message passing and threading framework that allows XML message passing from both client to server and server to client.

It can handle disconnections/reconnections, high client numbers and there's an optional virtual database library that will handle SQL server (or you could just use same SQL Server access you're using now).

It's not particularly well known yet but I can tell you that it's been actively developed over the last few years and that the author Misha is very keen to assist anyone who's interested in using it in their application.

LachlanG
Thanks - I will check this out.
M Schenkel
A: 

If you use Indy each connection will equal a thread.

Anyway, I suggest for connecting to MSSQL to use SDAC from Devart http://www.devart.com/sdac/ and for the connection layer to use HPScktSrvr based on I/O Completion Port from http://www.torry.net/authorsmore.php?id=7131 (I don't know though what changes it will need for TThread changes in newer VCL). You build your client class arround THPServerClient, you set your new class as the server ClientClass and the framework will create automatically new clients for you.

pani
A: 

You may also want to have a look at the ICS/Midware combo: http://www.overbyte.be/

Chee Meng
I will have to look back into ICS. I do in fact have this component. But as far as I knew it was a "TCP/IP" component which essentially does what Indy/IpWorks does. What I am ultimately looking for is a component which does connection management and database pooling all in one.
M Schenkel
ICS is the equivalent of Indy. Midware is a different product for multi-tier applications that happens to use ICS as the communications layer. They are two separate products from the same person. :-)
Ken White
+1  A: 

Well, it would probably require a complete rewrite of much of your C/S code, but instead of using the Indy components, you could try to use a COM+ solution instead. Basically, you would create a COM+ component that will be installed on the server and your client applications will connect to this client and call the functions of this component directly. It will have transaction management which will be handled by Windows itself and the same is true about handling transactions. It's also technically possible to create events, which would allow the server to do callbacks to the client, although that would make things a bit more complicated.
I don't think this solution would work out for you, though, unless you have a lot of experience with COM development in Windows and/or you're brave enough to try something different.
In the past, I had a similar problem where hundreds of clients had to connect to a single server, doing all kinds of database transactions. It has a steep learning curve but me and my team managed to get things working and once we understood the technique, it resulted in a very stable and reliable solution which did manage to have up to 500 users simultaneously doing updates and other actions in a one-time extreme stress-test. But again, the learning curse is steep, so it might not be the solution you're looking for.
(Still, COM+ will use a lot of functionality that's build-in into Windows, like transaction management, database pooling and whatever more.)

Workshop Alex
Thank you very much for the detailed answer. I don't in fact have COM experience. My expertise is pretty much limited to delphi components and 3rd party tools.
M Schenkel
Well, then forget what I said here. COM (and COM+) has a high learning curve in the beginning. But once you understand the technique, it can be real useful, allowing you to use standard Windows functionality without the need for any third-party components!
Workshop Alex
A: 

What about RemObjects DataAbstract?

Leonardo Herrera