iMan Biglari
iMan Biglari

Reputation: 4776

How to fire events in a Delphi application from another Delphi application?

Please read before tagging as duplicate.

I'm creating a set of applications which rely on smart cards for authentication. Up to now, each application has controlled the smart card reader individually. In a few weeks, some of my customers will be using more than one application at the same time. So, I thought maybe it would be more practical to create a service application which controls the authentication process. I'd like my desktop applications to tell the service application they are interested in the authentication process, and the service application would then provide them with information about current user. This part is easy, using named pipes. The hard part is, how can the service tell the desktop applications that an event has occurred (UserLogIn, UserLogOut, PermissionsChanged, ... to name a few). So far I have two methods in mind. CallBack functions, and Messages. Does anyone have a better idea? I'm sure someone has.

Upvotes: 5

Views: 3240

Answers (3)

Arnaud Bouchez
Arnaud Bouchez

Reputation: 43043

When it gets into IPC, some tips:

  • Do not be tied on one protocol: for instance, if you implements named pipe communication, you would later perhaps need to run it over a network, or even over HTTP;
  • Do not reinvent the wheel, nor use proprietary messages, but standard formats (like XML / JSON / BSON);
  • Callbacks events are somewhat difficult to implement, since the common pattern could be to implement a server for each Desktop client, to receive notifications from the server.

My recommendation is not to use callbacks, but polling on a stateless architecture, on the Desktop applications. You open a communication channel with the server, then every second / half second (use a TTimer in your UI), you make a small request asking for what did change (you can put a revision number or a time stamp of your last retrieval). Therefore, you synchronize your desktop data with pending events. Asking for updates on an existing connection is very fast, and will just send one IP packet over the network back and forth, if nothing changed. It is a very small task, and won't slow down nor the client nor the server (if you use some in-memory cache).

On practice, with real application, such a stateless architecture is very responsive, from the end-user point of view, and is much more easy to deploy. You do not need to create a server on each desktop application, so you don't have to open firewall ports or such. Since HTTP is stateless, it is even Internet friendly.

If you want to develop services, you can use DataSnap, something like RemObjects or you can try our Open Source mORmot framework which is able to create interface-based services with light JSON messages over REST, either in-process, using GDI messages, named pipes or TCP/HTTP - for free, with unbeatable performance, build-in security, and from Delphi 6 up to XE2. For your event-based task, just using the Client-Server ORM available in mORMot could be enough: create a table/class storing the events (you can even define a round-robin in-memory storage - no need to use SQLite3 engine nor a DB here), then ask for all pending events since the last refresh. And the server can safely be a background service, or a normal application - some mORMot users even have the same executable able to be either a stand-alone application, a server service, an application server, or a UI client, just by changing the configuration.

Edit / announcement:

On the mORMot roadmap, we added a new upcoming feature, to easily implement one-way callbacks from the server.

That is, add transparent "push" mode to our Service Oriented Architecture framework. Aim is to implement notification events triggered from the server side, very easily from Delphi code, via some interface definitions, even over a single HTTP connection - for instance, WCF does not allow this: it will need a dual binding, so will need to open a firewall port and such.

It will used for easy Event Collaboration, via a publish / subscribe pattern, and allow Event Sourcing. I will try to make it implement the two modes: polling and lock-and-wait. A direct answer to your question.

Upvotes: 5

Jeroen Wiert Pluimers
Jeroen Wiert Pluimers

Reputation: 24513

You want do to IPC (Inter Process Communication) with Delphi.

There are many links that can help you, Cromis IPC is just one to give you an idea what you are after.

A similar SO question to yours is here.

If you want to go pure Windows API, then take a look at how OutputDebugString communications is implemented.
Several tools can listen to the mechanism and many apps can send information to it.

Search for DBWIN_DATA_READY and DbWin32 for more information on how the protocol for OutputDebugString works.

This and this are good reading.

Upvotes: 10

mjn
mjn

Reputation: 36654

You can use a simple TCP socket connection (bidirectional) to allow asynchronous server to client messages on the same socket.

An example is the Indy TIdTelnetClient class, it uses a thread for incoming messages from the server.

You can build a similar text-based protocol and only need a Indy TCP server instance in the service, and one Indy Client instance in the application(s).

Upvotes: 0

Related Questions