You seem to have a bit of a misunderstanding of how TIdTCPServer
actually works.
The Bindings
collection has nothing to do with the individual clients. The Binding
items are simply the IP/Port pairs that the server listens on for connections. There is no mapping between a Binding
and a client. When a client connects, a TIdContext
object is created for it and stored in the server's Contexts
list, and then the OnConnect
/OnDisconnect
/OnExecute
events are triggered for that TIdContext
, independently of the other clients. TIdTCPserver
is multi-threaded, each client is run in its own dedicated thread, and the events for a given client are triggered within that client's thread, so events for multiple clients can be running in parallel.
The OnExecute
event is NOT dependent on a client polling the server. The event is simply called in a continuous loop for the lifetime of the client's connection. The event handler decides what to do with the client on each loop iteration. However, you are required to assign a handler, or else an exception will be raised when the server is activated (to avoid that, you can derive a new class from TIdTCPServer
and override its CheckOkToBeActive()
method to not raise an exception).
To send data to any particular client, simply locate that client's TIdContext
object within the server's Contexts
list, and then you will have access to its associated TIdTCPConnection
object for exchanging data with that client.
However, performing the send from inside the same loop that searches the Contexts
list is inheritantly unsafe, so I would suggest instead that you create a per-client thread-safe queue (such as a TIdThreadSafe(String|Object)List
instance) to hold your outbound data, and then when you locate the client you can put the data into that client's associated queue. Then you can have the OnExecute
event handler send the content of its client's queue whenever it is not empty. This way, you avoid clients blocking each other, error handling is localized to each client, and you can send data to multiple clients in parallel.
To associate a queue with each client, you can either:
use the public TIdContext.Data
property.
derive a new class from TIdServerContext
, add your own custom fields to it as needed, and then assign that class to the server's ContextClass
property before activating the server. You can then type-cast any TIdContext
object pointer to access your custom fields.
For a code example, see this answer I posted to an earlier question:
How do I send a command to a single client instead of all of them?