Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Jun : Re: FContextList problems Indy10.1.5
| Subject: | Re: FContextList problems Indy10.1.5 |
| Posted by: | "Jacques" (jacques.no..@btinternet.com) |
| Date: | Mon, 12 Jun 2006 00:47:12 |
I fixed the problem thanks for your help.
"Jacques" <jacques.noah@btinternet.com> wrote in message
news:448400cc@newsgroups.borland.com...
> Thanks Remy
>
> Since you have not specified how many clients are actually connected to
> your
>> server at the time
>
> At least five clients are connected to the server at any given time.
>
> Here's the code:
>
> Server Code
> type
> TMyContext = class(TIdContext)
> public
> IP: String;
> Nick: String;
> Con: TDateTime;
> procedure SendMsg(const Afrom,ANick: String; const AMsg:
> String);
> procedure BroadcastMsg(const bmsg: String);
> procedure BroadcastMsgAll(const ANick: String; const bmsg:
> String);
> procedure SendNicks;
> end;
>
>
> procedure TMyContext.SendNicks;
> var
> List: TList;
> Context: TMyContext;
> I: Integer;
> begin
> List := FContextList.LockList;
> try
> if List.Count > 0 then
> begin
> for I := 0 to List.Count-1 do
> begin
> Context := TMyContext(List[I]);
> if Context <> Self then
> //Send the list
> Connection.IOHandler.WriteLn('list@'+ Context.Nick);
> end;
> end else
> Connection.IOHandler.WriteLn('list@No other members
> available.');
> finally
> FContextList.UnlockList;
> end;
> end;
>
> //Here the connecting client details are collected
> procedure TForm1.tsConnect(AContext: TIdContext);
> begin
> with TMyContext(AContext) do
> begin
> Con := Now;
> if (Connection.Socket <> nil) then
> IP :=Connection.Socket.Binding.PeerIP;
> Nick := Connection.IOHandler.ReadLn;
> if Nick <> '' then
> begin
> Connection.IOHandler.WriteLn('Welcome ' + Nick + '!');
> BroadcastMsg(Nick + ' just joined!');
> end else
> begin
> Connection.IOHandler.WriteLn('No Nick provided! Goodbye.');
> Connection.Disconnect;
> end;
> end;
> end;
>
> procedure TForm1.tsExecute(AContext: TIdContext);
> var
> cmd,str:string;
> idx,posi:integer;
> begin
> //Break up the string sent by client to get the command
> str:=acontext.Connection.IOHandler.ReadLn;
> posi:=pos('@',str);
> cmd:=copy(str,1,posi-1);
> //Nicknames of all connected clients requested...
> if cmd='listnames' then begin
> TMyContext(AContext).SendNicks;
> end
> end;
>
>
> Client Code:
>
> TReadingThread = class(TThread)
> protected
> FConn: TIdTCPConnection;
> procedure Execute; override;
> public
> constructor Create(AConn: TIdTCPConnection); reintroduce;
> end;
> TLog = class(TIdSync)
> protected
> FMsg: String;
> procedure DoSynchronize; override;
> public
> constructor Create(const AMsg: String);
> class procedure AddMsg(const AMsg: String);
> end;
> IMPLEMENTATION
>
> constructor TReadingThread.Create(AConn: TIdTCPConnection);
> begin
> FConn := AConn;
> inherited Create(False);
> end;
>
> procedure TReadingThread.Execute;
> var
> s: String;
> begin
> while not Terminated and FConn.Connected do
> begin
> TLog.AddMsg(FConn.IOHandler.ReadLn);
> end;
> end;
>
> class procedure TLog.AddMsg(const AMsg: String);
> begin
> with Create(AMsg) do try
> Synchronize;
> finally
> Free;
> end;
> end;
>
>
> procedure TLog.DoSynchronize;
> var
> idx,i:integer;
> cmd, thelist:string;
> begin
> //FMsg is the string sent by the server you need to break this msg up to
> get the
> // command,msg and sender name
> //break up msg from server
> idx:=pos('@',FMsg);
> //get the command
> cmd:=copy(FMsg,1,idx-1);
> //list of names recieved
> if cmd='list' then begin
> thelist:= Copy(FMsg, Pos('@', FMsg)+1, Length(FMsg)-Pos('@', FMsg));
> //add the names to the listview
> form1.lnames.Clear;
> form1.li:=form1.lnames.Items.Add;
> form1.li.ImageIndex := 15;
> form1.li.caption:=thelist;
> end
> else
> form1.msg.Lines.Add(thelist);
> end;
>
> //this how the client request the list of names
> procedure TForm1.listnameClick(Sender: TObject);
> begin
> tc.IOHandler.WriteLn('listnames@fromname');
> end;
>
> *****************end code************
> A client request the list by sending a string containing a cmd called
> 'listnames' which as you can see from the Onexecute procedure of the
> server code is used to send a list of connected names.
>
>> Indy does have methods available for
>> reading/writing TStrings objects.
> Can you show how i can use those on the client side? I honestly thought
> that the entire list was sent in one go by the server. In future i will
> have upto 50 connected clients at any one time. Is there some way of
> knowing when the server has stopped sending the names on the Contextlist
> to the client? Or perhaps a way that i can change the SendNicks()
> procedure to send the list of names bundled up in something similar to a
> TString object and then sent off to the client in one go?
>
> Thanks
>
>
> "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
> news:4483d3a2$1@newsgroups.borland.com...
>>
>> "Jacques" <jacques.noah@btinternet.com> wrote in message
>> news:44823c37$1@newsgroups.borland.com...
>>
>>> I'm having problems retrieving a list of names of connected clients.
>>
>> That is because you are not doing it correctly to begin with.
>>
>>> when the list arrives at the requesting client only ONE of the many
>>> client names is shown.
>>
>> Given the limited code that you have shown so far, there are two
>> possibilities:
>>
>> 1) there is only 1 client in your list to begin with.
>>
>> 2) the client's reading code is wrong.
>>
>> Since you have not specified how many clients are actually connected to
>> your
>> server at the time, or when SendNick() is being called, or shown how the
>> client is reading back the list, there is no way to diagnose your problem
>> further. Please provide more details, and more complete code snippets.
>>
>>> FMsg is the entire 'list' sent by the server
>>
>> The server is sending the list as multiple strings, but the statement
>> above
>> suggests that you are processing the list as one big string instead. The
>> code you showed for processing FMsg is not setup for multiple lines,
>> unless
>> you are calling it in a loop that you have not shown yet.
>>
>>> Should i be creating a tstringlist to recieve the list on the client
>>> side?
>>
>> That would be a good thing to do, considering that you are sending the
>> list
>> as multiple strings to begin with. Indy does have methods available for
>> reading/writing TStrings objects.
>>
>>
>> Gambit