Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Jun : Re: IdTCPServer
| Subject: | Re: IdTCPServer |
| Posted by: | "Remy Lebeau (TeamB)" (no.spam@no.spam.com) |
| Date: | Thu, 8 Jun 2006 17:48:41 |
"Jamie Dale" <j.dale@turboz.net> wrote in message
news:4488c1bb@newsgroups.borland.com...
> well either way it using an array still allows me to keep all the
> users data and a pointer to the AThread. That means I can find
> their connection and write to it fairly easily.
You don't need to do any of that.
> Imagine if I assigned their info to the Thread data - I'd need
> blank threads for the users that wern't even logged on etc.
No, you don't. Just access the threads that are already running when
needed. If a user is not logged in, there would not be any thread at all.
> Using an array makes it a lot easier from my POV.
Only because you don't know any better yet. There are other ways to store
data more effectively. For example:
type
TMyPeerThread = class(TIdPeerThread)
private
WriteLock: TCriticalSection;
public
Username: String;
// other values as desired...
constructor Create(ACreateSuspended: Boolean = True); override;
destructor Destroy; override;
procedure SendToUser(const AUser, AMsg: String);
procedure SendFrom(const AUser, AMsg: String);
// other methods as desired...
end;
constructor TMyPeerThread.Create(ACreateSuspended: Boolean = True);
begin
WriteLock := TCriticalSection.Create;
inherited Create(ACreateSuspended);
end;
destructor TMyPeerThread.Destroy;
begin
WriteLock.Free;
inherited Destroy;
end;
procedure TMyPeerThread.SendToUser(const AUser, AMsg: String);
var
List: TList;
I: Integer;
begin
List := Connection.Server.Threads.LockList;
try
For I := 0 to List.Count-1 do
begin
with TMyPeerThread(List[I]) do
begin
if AnsiSameText(Username, AUser) then
begin
SendFrom(Self.Username, AMsg);
Exit;
end;
end;
end;
finally
Connection.Server.Threads.UnlockList;
end;
end;
procedure TMyPeerThread.SendFrom(const AUser, AMsg: String);
begin
WriteLock.Enter;
try
Connection.WriteLn(Format('MSG %s %s', [AUser, AMsg]));
finally
WriteLock.Leave;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPServer1.ThreadClass := TMyPeerThread;
IdTCPServer1.Active := True;
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
with TMyPeerThread(AThread) do
begin
Username := AThread.Connection.ReadLn;
// other values as desired...
end;
end;
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
LLine, LCmd, LUser: String;
begin
LLine := AThread.Connection.ReadLn;
LCmd := Fetch(LLine);
if AnsiSameText(LCmd, 'MSG') then
begin
LUser := Fetch(LLine);
TMyPeerThread(AThread).SendToUser(LUser, LLine);
end;
//...
end;
> Also, seeing as each thread has access to the array, how can
> I stop it being damaged/corrupted?
> Can you provide any sample codes?
One way would be to stop using an array to begin with.
Another way would be to lock access to the array using a critical section,
which was already suggested to you in an earlier discussion.
Gambit