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

Please read before marking as duplicate.

I am creating a set of applications that rely on smart cards for authentication. So far, each application has controlled the smart card reader individually. In a few weeks, some of my clients will be using multiple applications at once. Therefore, I thought it would be more practical to create a service application that controls the authentication process. I would like my desktop applications to inform the service application that they are interested in the authentication process, and the service application will then provide them with information about the current user. This part is simple using named pipes . The tough part is how the service can tell desktop applications that an event has occurred ( UserLogIn , UserLogOut , PermissionsChanged , ... to name a few). So far I have two methods. CallBack and Messages . Anyone have a better idea? I'm sure someone has it.

+4
source share
3 answers

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

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

A similar SO question for you here .

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

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

This and this is a good read.

+9
source

When it gets into IPC, some tips:

  • Do not get attached to one protocol: for example, if you implement a named connection with a pipe, later you may need to run it over the network or even through HTTP;
  • Do not reinvent the wheel or use proprietary messages, but standard formats (for example, XML / JSON / BSON);
  • Events with callbacks are somewhat difficult to implement, since a common template can be a server implementation for each desktop client to receive notifications from the server.

My recommendation is not to use callbacks, but polling in a stateless architecture in desktop applications. You open a communication channel with the server, then every second / half a second (use TTimer in the user interface), you make a small request asking what has changed (you can put the version number or timestamp of your last search). Therefore, you synchronize your desktop data with pending events. Requesting updates on an existing connection is very quick and easy to send one IP packet over the network back and forth if nothing changes. This is a very small task and will not slow down the work of either the client or the server (if you use some cache in memory).

In practice, with a real application, such a stateless architecture is very responsive, from the point of view of the end user, and it is much easier to deploy. You do not need to create a server for each desktop application, so you do not need to open firewall ports or such. Since HTTP is stateless, it is even Internet friendly.

If you want to create services, you can use DataSnap, something like RemObjects , or you can try our Open Framework mORmot framework , which is able to create services based on the interface with light JSON REST messages, or in the process using GDI messages, named pipes or TCP / HTTP - for free, with unrivaled performance, built-in security, and from Delphi 6 to XE2. For your event-based task, just using the ORM Client-Server available in mORMot might be enough: create a table / class that stores events (you can even define a circular storage in memory - there is no need to use the SQLite3 and DB engine here), and then request all pending events since the last update. And the server can safely be a background service or a regular application - some mORMot users even have the same executable file, which can be a standalone application, server service, application server or user interface client, just changing the configurations.

Edit / Announce:

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

That is, add a transparent push mode to our Service Oriented Architecture. The goal is to implement notification events triggered by the server, very easily from Delphi code, through some interface definitions, even over a single HTTP connection - for example, WCF does not allow this: it requires double binding, so you need to open the port firewall etc

It will be used for easy Event Collaboration through the publish / subscribe template and enable Event Sourcing . I will try to implement it in two modes: polling and blocking and waiting. Direct answer to your question.

+5
source

You can use a simple TCP socket connection (bidirectional) so that the asynchronous server can receive client messages on the same socket.

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

You can create a similar text protocol and you only need an instance of the Indy TCP server in the service and one instance of the Indy Client in the application (s).

0
source

Source: https://habr.com/ru/post/1432450/


All Articles