Hi Guys, please I need some help here.
I am doing a program that uses indy with delphi 7. I had a technical question and sent my question to the support of the indy component:
My question was:
//////////////////////////
//////////
//////// My Question to indy support
Hi,
I am using delphi 7 with indy 10.2.3 and TidTCPServer
I did this in my program (only a test):
type
TMyContext = class(TIdContext)
public
user_id: integer
procedure SendMsg(const ID: Integer);
end;
In OnConnect event of TidTCPServer i did this:
with TMyContext(AContext) do
begin
user_id:=strtoint(Connecti
on.IOHandl
er.ReadLn)
;
Connection.IOHandler.Write
Ln('User ' + inttostr(user_id) +
'connected');
end;
In OnExecute i did this:
var
touser:integer
begin
touser:=strtoint(AContext.
Connection
.IOHandler
.ReadLn);
TMyContext(AContext).SendM
sg(touser)
;
end
And in SendMsg procedure a did this:
procedure TMyContext.SendMsg(const ID: Integer);
var
List: TList;
Context: TMyContext;
I: Integer;
begin
List := FContextList.LockList;
try
for I := 0 to List.Count-1 do
begin
Context := TMyContext(List[I]);
if Context.user_id = ID then
begin
try
Context.Connection.IOHandl
er.WriteLn
('Hi');
except
end;
Exit;
end;
end;
finally
FContextList.UnlockList;
end;
end;
Well, when a client send the number of another client, this client receives
the message 'HI'.
Now i need read a table in my data base and get the user_id, and then send
to the right connection. I dont know how do this outside of OnExecute event.
//////////////////////////
//////////
//////////
//////////
//////////
//////////
End Of my question
Well, the answer was:
///////////// The answer
In order for that to work properly, you need to implement a locking
mechanism in your Context class so that multiple threads cannot write to the
same client at the same time (locking the ContextList is not enough). The
alternative is to implement a FIFO queue in the Context class that SendMsg()
simply appends to, and then have the OnExecute handler write out the
contexts of the queue peridoically.
> Now i need read a table in my data base and get the user_id, and
> then send to the right connection. I dont know how do this outside
> of OnExecute event.
Yes, you do, because your SendMsg() method is already doing it. The
TIdContext.FContextList member points to the same list that the
TIdTCPServer.Contexts property points to, and that property is declared as
public, so any code you have that can reach the TIdTCPServer object can
access the Contexts list.
///////////////////// End of answer
Please Guys, I need help to develop this locking mechanism in my Context class.
Can someone help me?
Thx
Start Free Trial