I was recently given the task to write an application in Delphi XE6 that communicates with our legacy system (Delphi 2007). The old system uses TWSocket to drive the communication using its OnDataAvailable event on a socket level. TClientSocket and TServerSocket are also used and since those have been deprecated i would prefer to use modern components to replace them on my end.
Is it possible to use the components supplied in Delphi XE6 (i.e. TIdTCPClient, TIdTCPServer)?
Could you point to an example where this is done?
Indy surely can be used as a replacement for these old / deprecated socket libraries.
OnDataAvailable is an asynchronous, non-blocking event handler, which requires a different programming style than Indy, which uses blocking TCP communication.
And depending on your specific code, the Indy components should be used in a separate thread to run independent of the application main thread.
Related
How can I communicate with CEF via Indy Sockets through Remote debugging protocol?
As described here: https://developers.google.com/chrome-developer-tools/docs/debugger-protocol
I made a Proof of Concept for DWS (pascal to javascript compilation, as used in Smart Mobile Studio) some time ago:
https://code.google.com/p/asmprofiler/source/browse/#svn%2Ftrunk%2F-Other-%2FRemoteDebuggerDWS
You can use my Indy 10 websocket (and socket.io!) components from here:
https://github.com/andremussche/DelphiWebsockets
The API currently requires using the WebSocket protocol which is not supported in Indy. The API documentation page contains this note:
Note that we are currently working on exposing an HTTP-based protocol
that does not require client WebSocket implementation.
There are WebSocket client libraries available for Delphi both free and commercial (some use Indy as their internal TCP library).
You will also need a JSON library, available in newer Delphi versions and also as free open source (for example SuperObject and lkJSON).
I use WM_COPYDATA to enable communication between my two processes A and B. There is no problem to exchange data with basic data types.
Now I have a problem, in some case I want to pass an Interface (IDispatch) from my process A to my process B. Is it possible?
It is not possible to directly pass an interface pointer to another process. Like any other pointer, an interface is only valid in the process address space that instantiates it at runtime. COM has its own mechanism for marshaling interfaces and data across process boundaries, even across different apartments in the same process. In the case of interfaces, that involves proxies and stubs which run in each process/apartment and communicate with each other using various IPC mechanisms, such as pipes, RPC, or TCP/IP. Have a look at these articles for how using interfaces across processes/apartments is accomplished:
Inter-Object Communication
Understanding Custom Marshaling Part 1
To do what you are asking for, without resorting to implementing custom marshaling, you would have to make one of the processes act as an out-of-process COM server, and then the other process can use CoCreateInstance() or GetActiveObject() to obtain an interface pointer to the server's object that works within its local address space, and let COM handle the marshaling details for you.
It can't be done directly, but you can use a Client-Server service framework, which may be interface based.
For instance, see the last feature of our Open Source mORMot framework: Interface based services sample code and this link.
You can execute an interface on a remote process. The feature handles all communication means of the framework, i.e. in-process call, GDI messages, named pipes and TCP/HTTP. Internally it will use WM_COPYDATA for GDI messages, then transmit the parameters and results as JSON. Use this link to download the source code (use the http://synopse.info/fossil 1.16+ version) and the documentation (there are several pages about how to implement those services).
It is an Open-Source project, working with Delphi 6 up to XE2.
You can also expose your interface with a SOAP or DataSnap Client-Server (if you have the corresponding version of Delphi), or n-Tier commercial packages (like http://www.remobjects.com/da). This is similar to the method implemented in mORMot.
COM is also a good candidate, native to Windows, but it is more difficult to initialize: you'll have to register the COM on each PC (with administrator rights), and you won't be able to make it work over a network (DCOM is deprecated, remember). COM is good if you want your service to be shared with other languages, like .Net, but only locally.
We have a C/S application all written in Delphi (Client and Server-or middleware if you want)
For the client part we use Indy.
For the server we use DXSock.
Since DXSock is dead for a while we are investigating alternatives for the sever part.
I want to hear some comments about the best Server Socket alternative component for Delphi.
The current system usually have tens of permanent connections working each one on its own thread but could be hundreads in the future (this should be improved to a thread pool if possible)
If you want to have the best possible performance, you'd have to use sockets in non blocking mode, or using completion ports. IPWorks is implemented like that, as well as iocp. As far as I can tell, Indy or Synapse don't implement them (at least officially).
We used completion ports and a thread pool in our open source SynCrtSock unit, used in our Synopse SQLite3 framework.
Here are some benchmarks of this solution, working from Delphi 6 up to Delphi XE. I don't tell this is the "best component", but it's a working and speedy one (every request is about 4 KB of JSON data):
Http client keep alive (i.e. one HTTP/1.1 client connection kept alive during requests):
first in 7.87ms, done in 153.37ms i.e. 6520/s, average 153us
Http client multi connect (i.e. one new HTTP/1.0 client connection created for each request - this one uses completion ports and a thread pool):
first in 151us, done in 305.98ms i.e. 3268/s, average 305us
For speed comparison, here are other communication protocols available in our framework:
Named pipe access:
first in 78.67ms, done in 187.15ms i.e. 5343/s, average 187us
Local window messages:
first in 148us, done in 112.90ms i.e. 8857/s, average 112us
Direct in process access:
first in 44us, done in 41.69ms i.e. 23981/s, average 41us
We use HTTP/1.1 protocol over TCP/IP, because there is very little overhead over plain TCP/IP, and this is a well handled protocol for firewalls and such, and allows our framework to be used by an AJAX application, whereas its main purpose is to serve Delphi clients.
IMHO there is no "best Server Socket alternative component for Delphi", it depends what is the purpose of your server application. The main bottleneck will be in the Windows kernel itself. Perhaps direct access to the HTTP Kernel-Mode Driver (Http.sys) of Windows could help.
Consider using a dedicated optimized Server instead of a Delphi server, like lighttpd or Cherokee using FastCGI to handle the requests via a Free Pascal (or CrossKylix) application, under Linux. I guess this will be the best performance possible.
I use Indy components for commercial server-side work and the component set is pretty solid (9 or 10). My servers have millions of connections per day with no issues.
I used DXSock many moons ago. He was always optimizing, but never seemed to finish it. He does seem to have another version out.
If you want commercial support, then I'd recommend IPWorks from nSoftware.
Actually DXSock is not dead, v6.1 was just released. The web hosting company we used to use in Tennessee lost the domain - so only customers who have kept their subscription renewed annually have received DXSock 5.0, 6.0 and 6.1.
Indy CANNOT support more than 2,000 concurrent connections on 32bit Windows - as Chad and crew use TThread, which implements the defacto 1MB per thread/socket connection - 2000x1MB = >2.5GB of RAM which 32bit OSes do not support. DXSock implements a 0b per connection model (unless you define otherwise) and can handle over 50,000 concurrent on Windows, Linux, Mac, Pi, etc.
Ozz Nixon - ozznixon#bpdx.com if you want more details on 6.1
Author of DXSock
Co-Author of Winshoes which became INDY.
I'm using Delphi 4, and I want to create a standard non blocking socket with out the clutter of Indy code (Pv4 and Pv6). and i want to get the computers IP address and be able to ping has any one done this. Can I do it with Indy 10 or Indy 9. And has any one made code up to do any of these things and tested it please.
Indy officially stopped supporting Delphi 4 a long time ago. Delphi 5 is the earliest version still supported. Delphi has its own socket classes - TClientSocket and TServerSocket - which can operate in both blocking and non-blocking modes. Indy operates strictly in blocking mode only.
Without using Indy, you can get the machine's IP(s) using either the WinSock API's gethostname and gethostbyname functions, or the Win32 API's GetAdapterAddresses or related functions, and use the Win32 API IcmpSendEcho function to ping.
Has anyone had any experience of talking between an iSeries (using IBM's Websphere MQ) and PC code - hopefully using Delphi 2009.
Modification:
I have a large PC based program (that talks to an iSeries) that I need to rewrite. One option would be to do most of the tricky and processor intensive processing on the iSeries and then have that program signal the PC based program (written in Delphi at the moment) to do the part of the processing that are best done on the PC. So I need to signal the final part somehow from the iSeries, without it polling the iSeries all the time.
First option: add a Java app to the Delphi side which uses a JMS client to listen to an event topic on the MQ server, which receives a complete message from the worker process and forwards this message to the Delphi app (over TCP/IP or other simple IPC methods).
Second option: implement a simple web service server in the Delphi app which has only one method notify() and call this service from the WebSphere side. An example for a stand-alone SOAP server for Delphi 7 (but can be modified to work with D2009 too) using Indy can be found here.
I haven't tried to get it to work, but this looks interesting - http://jamiei.com/blog/2009/02/Delphi-mqtt-client/