Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Jun : Re: FContextList problems Indy10.1.5

www.cryer.info
Managed Newsgroup Archive

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

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive