Search code examples
delphidelphi-2009client-serverindy

Robust unidirectional messages with Indy


I have a client application that should send notify messages to an optional server application. The client should not be influenced by whether the server appliction exists or not. It should try to connect to the server application and send the notify message and in case of errors it should just silently ignore all errors and continue work.

I'm using Indy for the TCP communication but all attempts to avoid error messages showing up (i.e. when ther server application closes while connected to the client) failed.

Is there a way to really make this robust?

Current code looks like this:

if (not Client.Connected) then
  begin
  Client.Host := ServerName;
  Client.Port := ServerPort;
  Client.ConnectTimeout := ConnectTimeout;
  try
    Client.Connect;
  except
    Exit;
  end;
  end
try
  Client.IOHandler.WriteLn ('NOTIFYCHANGE "' + Param + '"');
  Client.IOHandler.WriteBufferFlush;
except
  try
    Client.Disconnect;
  except
    { ignore errors while disconnecting }
  end;
  try
    Client.Connect;
  except
    { ignore errors while connecting }
  end;
end;

Solution

  • Do you really get error messages from your program? It's common that when debugging that the debugger detects exceptions and interrupts your program, and some people confuse the debugger's message for a message from their own program. Are you sure that's not the case here? I've written about this situation before. Here's the summary of ways to avoid it:

    • Use "advanced breakpoints" to disable the debugger's exception-interception behavior for a region of code.
    • Configure the debugger to ignore certain classes of exceptions. (This is especially common to do with Indy since it tends to throw many exceptions.)
    • Set the debugger to never interrupt the program on exceptions.
    • Disable integrated debugging altogether.

    If the message really is coming from your program and not the debugger, then go back and use the debugger to figure out where the message is coming from. When the message appears, pause the program and look at the call-stack window to find the area of your code that's displaying the message, since it clearly isn't in the code you've shown. The code you've shown is thoroughly suppressing (not handling) all exceptions, even the ones that aren't related to Indy, such as EAccessViolation and EOutOfMemory.