Good day,
I'm supposed to communicate with a Server that receives XML messages and sends XML data back, occasionally (every 30 seconds when there were no other messages passed) the server sends a KeepAlive XML message without the client asking for it, but the client has to answer to the message. So I have a TReceiveThread class, derived from TThread, that gets passed the TIdTCPClient which was created in the main thread aswell as a TCriticalSection for synchronization, implemented .Execute to check once a second if a KeepAlive message arrived and sends an answer back to the server.
.Execute (pseudo code):
.Execute
while not Terminated
TThread.Sleep(1000)
lock.enter
try
try
recevied data (exception on timeout)
if message type is keepalive
send ack message
except
end
finally
lock.leave
end
So far so good.
Now I want to send other messages, for example on a button click from the main thread (pseudo code):
create xml message
lock.enter
try
try
send xml message
read data (exception on timeout)
parse data
except
report timeout error
end
finally
lock.leave
end
This also works with every message I've implemented.
However, when I'm not sending a message for 30 seconds so the server sends a KeepAlive message that gets handled and answered in the thread, the next message I'm trying to send from the main thread will throw a EIdReadTimeout (I can see the data sent in Wireshark, but not the data received). When I then send the same message again I'm getting an answer. I've extensively checked for synchronization errors and dead data in the send/receive buffers, that all seems to be fine.
when I change the code above to:
create xml message
lock.enter
try
try
try
read data (exception on timeout) <------
except
end
send xml message
read data (exception on timeout)
parse data
except
report timeout error
end
finally
lock.leave
end
as if the first read in the main thread somehow changes the context so the second read works as expected
any advice?