views:

1431

answers:

5

I have a classic client/server (fat client and database) program written in Delphi 2006. When certain conditions are met in the client, I need to notify all the other clients very quickly. Up until now this has been done using UDP broadcasts, but this is no longer viable as clients now connect from outside the LAN and the UDP broadcast is limited to the local network.

I'm aware of the Indy libraries but am not really sure of which components to use and how to structure it. I'm guessing I'll need to have a server that the clients connect to which will receive and distribute the messages...? Any samples out there to get me started?

Are there any other component sets or technologies I should look at instead/as well?

A: 

You should be able to use Multicast UDP for the same purpose. The only difference will be to join the multicast group from every client.

http://en.wikipedia.org/wiki/IP_Multicast

http://en.wikipedia.org/wiki/Internet_Group_Management_Protocol

Edit: Just to clarify, multicast let you join a given "group" associated to a multicast ip address. Any packet sent to that address will reach every client who has join the group

Jorge Córdoba
+1  A: 

The simple answer is that the standard protocols available in Delphi (and other tools) don't allow for notification in reverse. I looked into this for a project where I wanted to use SOAP. They all assume client asks server, server responds and that's it.

For me, the solution was the RemObjects SDK. This allows you to send notifications to clients, and the notification can have any data you like (just like the client to server). Myself I use the SuperTCP connection, but it works with others too. It can still offer a SOAP interface for clients that must use it, but for where you have control of both client and server it works extremely well.

mj2008
They do allow for notifications in reverse, it just isn't immediately obvious since the connections need to already be made, or be made at regular intervals to check for the notifications.
Jim McKeeth
A: 

There are a few really easy ways to do this with Delphi, although I am sure the RemObjects SDK works really well too.

  1. Have a central server that has a * TIdTCPServer listening* on it. Then each client has a TIdTCPClient on it. They connect to the server and block on a read waiting for the server to write. Once the server receives a notification via a listening socket it broadcasts to each of the waiting clients. This is pretty much immediate notification of all the clients.
  2. Have a central server that has a TIdTCPServer listening on it. Then each client has a TIdTCPClient on it. Those clients can "ping" the server to ask for updates at a regular interval (use a session token to maintain state). The frequency of the interval determines how quick the notification will be. When once one of the clients needs to notify the others, it just notifies the server. The server then uses a message queue to make a list of all active client sessions and adds a notification for each. Then the next time each of the clients connects it gives it the notification and remove it from the queue.
  3. Maintain a session table in the database where each client updates regularly that they have an active session, and removes itself when it disconnects. You will need a maintenance process that removes dead sessions. Then you have a message queue table that a client can write an update to with one row for each current active session. Then the other clients can regularly ping that table to see if there are any pending notifications for its session, if there are it can read them, act on them and then remove them.
  4. Some sort of peer to peer approach were the clients are aware of each other through information in the database and then they connect directly to each other and notify or ask for notifications (depending on firewall and NAT configurations). A little more complex, but possible.

Obviously the choice of implementation will depend on your setup and needs. Tunning will be necessary to achieve the best results.

The components you need for this are the TIdTCPServer (listener) and TIdTCPClient (sender). Both of which are in the Indy libraries in Delphi.

Jim McKeeth
A: 

ICS components from http://www.overbyte.be are great. a.) Better compatibility than Indy b.) PostCard ware Good examples and support. Use TClientSocket and TServerSocket

A: 

FirebirdSQL project use the concept of notifications as being server-client connections that send a string to the client. For this, the db server uses an other port. And require the client to register it's interesting of receiving a certain type of notification through an API call.

You could use the same idea.

Fabricio Araujo