I use this snippet to create a new instance of an Indy10 TCPServer:
procedure TPortWindow.AddPort (Item : TListItem);
var
Socket : TIdTcpServer;
begin
Socket := TIdTcpServer.Create(nil);
try
Socket.DefaultPort := strtoint (item.Caption);
Socket.OnConnect := MainWindow.OnConnect;
Socket.OnDisconnect := MainWindow.OnDisconnect;
Socket.OnExecute := MainWindow.OnExecute;
Socket.Active := TRUE;
except
Socket.Free;
OutputError ('Error','Port is already in use or blocked by a firewall.' + #13#10 +
'Please use another port.');
Item.Data := Socket;
Item.Checked := FALSE;
end;
end;
I use this to Delete the instance:
procedure TPortWindow.RemovePort (Item : TListItem);
var
Socket : TIdTcpServer;
begin
if Item.Data = NIL then Exit;
Socket := TIdTcpServer(Item.Data);
try
Socket.Active := FALSE;
finally
Socket.Free;
end;
Item.Data := NIL;
end;
For some reason the instance does NOT stop listening and all clients stay connected. When I try to make a new instance of the previous Port (after the deletion) it says, that the port is already in use which means it did not stop listening.
How can I properly Shutdown this Instance (and also disconnect all connected clients)?
EDIT:
procedure TMainWindow.OnConnect(AContext: TIdContext);
begin
ShowMessage ('connected');
end;
procedure TMainWindow.OnDisconnect(AContext: TIdContext);
begin
ShowMessage ('disconnected');
end;
procedure TMainWindow.OnExecute(AContext: TIdContext);
begin
// Not defined yet.
end;
Setting the Active
property to False is the correct thing to do. It will automatically close the listening port(s) and close any active client connections.
What you do need to watch out for, however, is make sure that your server event handlers are not performing any synchronized operations to the main thread while the main thread is busy deactivating the server, otherwise a deadlock will occur.