I don’t know why using OnConnect and OnDisconnect will not work for you, but we did this to create a descendant of TIdCustomTCPServer; override the DoConnect and DoDisconnect methods and create and use your own descendant TIdServerContext (a stream descendant that will "serve" the connection).
You tell TIdCustomTCPServer about your own TIdServerContext class:
( Modify Added conditional definitions to show how to make it work for Indy9)
type // Conditional defines so that we can use the same ancestors as in Indy10 and we // can use the same method signatures for DoConnect and DoDisconnect regardless // of the Indy version. Add other conditional defines as needed. // Note: for INDY9 to be defined, you need to include the appropriate includes // from Indy, or define it in your own include file. {$IFDEF INDY9} TIdContext = TIdPeerThread; TIdServerContext = TIdContext; TIdCustomTCPServer = TIdTCPServer; {$ENDIF} TOurContext = class(TIdServerContext) private FConnectionId: cardinal; public property ConnectionId: cardinal ...; end; ... constructor TOurServer.Create(aOwner: TComponent); begin inherited Create(aOwner); ... {$IFDEF INDY10_UP} ContextClass := TOurContext; {$ELSE} ThreadClass := TOurContext; {$ENDIF} ... end;
In overriding the DoConnect of our descendant TIdCustomTCPServer, we set the ConnectionID of our context class to a unique value:
procedure TOurServer.DoConnect(AContext: TIdContext); var OurContext: TOurContextabsolute AContext; begin Assert(AContext is TOurContext); HandleGetNewConnectionID(OurContext, OurContext.FConnectionID); inherited DoConnect(AContext); ... end;
Our DoDisconnect override clears the ConnectionID:
procedure TOurServer.DoDisconnect(AContext: TIdContext); var OurContext: TOurContextabsolute AContext; begin Assert(AContext is TOurContext); OurContext.FConnectionID := 0; ... inherited DoDisconnect(AContext); end;
Now you can get a count of current connections at any time:
function TOurServer.GetConnectionCount: Integer; var i: Integer; CurrentContext: TOurContext; ContextsList: TList; begin MyLock.BeginRead; try Result := 0; if not Assigned(Contexts) then Exit; ContextsList := Contexts.LockList; try for i := 0 to ContextsList.Count - 1 do begin CurrentContext := ContextsList[i] as TOurContext; if CurrentContext.ConnectionID > 0 then Inc(Result); end; finally Contexts.UnLockList; end; finally MyLock.EndRead; end; end;
source share