You just need a connection between the DSServer1Connect
with the classes ServerMethods
. The idea here is to store the information in an array for example and retrieve it later from within the ServerMethods
.
First of all declare a class in Unit ServerConteiner
:
type
TConexao = class
IP: String;
ClientPort: String;
Protocol: String;
AppName: String;
end;
After that, within the sector public
of ServerContainer
we will create a variable to store these connections, in case it will be a TDictionary
:
public
ConnectionList: TDictionary<Integer, TConexao>;
Now we have a variable with public reach, able to store the information of all the necessary connections. We need to create it in the event DataModuleCreate
of ServerContainer
:
procedure TServerContainer1.DataModuleCreate(Sender: TObject);
begin
ConnectionList := TDictionary<Integer, TConexao>.Create;
end;
With that prepared, we will make the procedure TServerContainer1.DSServer1Connect
use this variable:
procedure TServerContainer1.DSServer1Connect(
DSConnectEventObject: TDSConnectEventObject);
var
conexao: TConexao;
begin
if ConnectionList.ContainsKey(TThread.CurrentThread.ThreadID) then
begin
ConnectionList[TThread.CurrentThread.ThreadID].IP := DSConnectEventObject.ChannelInfo.ClientInfo.IpAddress;
ConnectionList[TThread.CurrentThread.ThreadID].ClientPort := DSConnectEventObject.ChannelInfo.ClientInfo.ClientPort;
ConnectionList[TThread.CurrentThread.ThreadID].Protocol := DSConnectEventObject.ChannelInfo.ClientInfo.Protocol;
ConnectionList[TThread.CurrentThread.ThreadID].AppName := DSConnectEventObject.ChannelInfo.ClientInfo.AppName;
end
else
begin
conexao := TConexao.Create;
conexao.IP := DSConnectEventObject.ChannelInfo.ClientInfo.IpAddress;
conexao.ClientPort := DSConnectEventObject.ChannelInfo.ClientInfo.ClientPort;
conexao.Protocol := DSConnectEventObject.ChannelInfo.ClientInfo.Protocol;
conexao.AppName := DSConnectEventObject.ChannelInfo.ClientInfo.AppName;
ConnectionList.Add(TThread.CurrentThread.ThreadID, conexao);
end;
end;
We store the values within the TDictionary
, and notice, before creating a new record we see if it already exists through the global location variable, which is the key to that dictionary TThread.CurrentThread.ThreadID
.
It would be interesting also in disconnecting remove this record to not keep weighing in memory, so the event TServerContainer1.DSServerDisconnect
would be:
procedure TServerContainer1.DSServerDisconnect(DSConnectEventObject: TDSConnectEventObject);
begin
ConnectionList[TThread.CurrentThread.ThreadID].Free;
ConnectionList.Remove(TThread.CurrentThread.ThreadID);
end;
So when disconnecting we release the instantiated object TConexao
memory through the method Free
and then remove that space from our dictionary. We could release the dictionary variable completely from memory in the event DataModuleDestroy
of ServerContainer1
:
procedure TServerContainer1.DataModuleDestroy(Sender: TObject);
begin
ConnectionList.Clear;
ConnectionList.Destroy;
end;
Now finally to access your Unit data ServerMethods
just add no uses to Unit ServerConteiner
, and access the dictionary that is public, let’s see:
uses
{unit já existentes...}, ServerConteiner;
{... declarações da unit ...}
function TServerMethods.ReverseString(Value: string): string;
begin
// Acessando a seguir a informação para usar da forma que preferir.
ServerContainer1.ConnectionList.[TThread.CurrentThread.ThreadID].IP;
Result := System.StrUtils.ReverseString(Value);
end;
That’s basically it, that way you create a global information gateway on your application server.
Solution at: http://blog.atlabs.com.br/2017/06/delphi-pegando-o-ip-cliente-em-um.html
– Felipe Leal