Конференция "Сети" » список активных клиентов (Indy) [D7, WinXP]
 
  • Gekanaz (12.10.11 22:02) [20]

    > Как это "сама удаляет" ?
    > Св-во Data - это нетипизированный указатель, откуда серверу
    > знать что за ним кроется и как это "удалять" ?
    >
    >

    согласен с вами :)  , память почищу при дисконнекте методом destroy если не ошибаюсь, но думаю проблему это не решит
  • Сергей М. © (12.10.11 22:07) [21]

    > TMyData = class //индивидуальные данные каждого коннекта
    >  public
    >    id:integer;//
    >    logg:boolean;//
    >    xxx : integer;
    >    Name : string; // а это что ?
    >  end;
  • Gekanaz (12.10.11 22:12) [22]
    procedure TForm1.servCommandHandlers0Command(ASender: TIdCommand);
    //Name это имя юзера оно заполняется при авторизации
    Tmydata(asender.Context.Data).name:=asender.Params[0];
  • Сергей М. © (12.10.11 22:21) [23]
    в [18] приведен полный код обработчика команды.
    Что-то я в упор не вижу там ни единого обращения к св-ву Name ..
  • Gekanaz (12.10.11 22:24) [24]
    procedure TForm1.servCommandHandlers0Command(ASender: TIdCommand);
    begin

    q.SQL.Text:='select ID,XXX,B from client where nikname=:ni and pass=:pa';
    q.Params[0].Value:=asender.Params[0];
    q.Params[1].Value:=asender.Params[1];
    q.Open;
    if not q.Eof then
    begin  
      asender.Response.Add('USERDATA '+intToStr(Q.Fields[1].value)+' '+intToStr(q.Fields[2].value));
      Tmydata(asender.Context.Data).id:=Q.Fields[0].value;
      Tmydata(asender.Context.Data).xxx:=Q.Fields[1].value;
      Tmydata(asender.Context.Data).logg:=true;
      Tmydata(asender.Context.Data).name:=asender.Params[0]; // это было добавлено чуть позже...  а скопировалось из старого кода
      memo1.Lines.Add('Login '+asender.Params[0]+'='+Tmydata(asender.Context.Data).ip);
    end else
    begin// user not found
      asender.Response.Add('USERNULL 0');
    end;
    end;
  • Сергей М. © (12.10.11 22:34) [25]

    > в этом же цикле я добавляю имя клиента в Memo


    for i:=0 to list.count-1 do
    begin
     q.params[0].asinteger:=TMyData(TIdContext(List.Items[i]).Data).xxx; // !!!
    ...
     Memo1.lines.add(q.params[0].asinteger); // какое же это "имя клиента", если ты САМ сказал что имя клиента хранится в св-ве Name, а не в порно-свойстве ?
    end;
  • Gekanaz (12.10.11 22:50) [26]
    Memo1.lines.add(q.params[0].asinteger) - это дописывал от руки (полного кода с собой нет, поэтому ошибся
    Memo1.lines.add(TMyData(TIdContext(List.Items[i]).Data).name);  //это отладочная строка, потом будет удалена..
  • Сергей М. © (12.10.11 22:55) [27]
    т.е. ты утверждаешь что значения порносвойства xxx и св-ва Name в каждом объекте класса TMyData одинаковы и содердат имя клиента ?
  • Gekanaz (12.10.11 23:00) [28]
    for i:=0 to list.count-1 do
    begin
     q.params[0].asinteger:=TMyData(TIdContext(List.Items[i]).Data).xxx; //это порносвойство будет хранить количество коннектов :) этого клиента
     q.params[1].asinteger:=TMyData(TIdContext(List.Items[i]).Data).id;
     q.ExecSQL;
     Memo1.lines.add(TMyData(TIdContext(List.Items[i]).Data).name);  //это отладочная строка, потом будет удалена..
    end;

    xxx и name  даже разного типа и содержат разную инфу
  • Сергей М. © (12.10.11 23:13) [29]
    а где у тебя в обработчике servDisconnect() протоколирование имени отключившегося клиента ?
    не вижу ..
  • GekaNaz (13.10.11 08:21) [30]
    в [8] писал, что не сделал этого еще, но пока это не важно... я сам знаю, что я отключил Васю, почему Count не уменьшается вот это не понятно
  • Медвежонок Пятачок © (13.10.11 09:16) [31]
    при отключении юзера ставить флаг неактивности в его блоке данных.
    при обработке листа учитывать значение флага.
    локлист и анлок лист поместить в try/finally
  • Сергей М. © (13.10.11 09:40) [32]

    > я сам знаю, что я отключил Васю


    А я вот не знаю что отключил ты именно Васю.
    Предлагаешь верить тебе на слово и прочим чудесам ?)


    > почему Count не уменьшается


    Как это не уменьшается, если

    > подключился второй.. третий
    > при отключении второго юзера (из трех) count становится равным 2

    ?

    И не уменьшаться он НЕ может, если неопровержим факт возникновения события сервера OnDisconnect
  • Сергей М. © (13.10.11 09:50) [33]

    > Медвежонок Пятачок ©   (13.10.11 09:16) [31]
    >
    > при отключении юзера ставить флаг неактивности в его блоке
    > данных.


    Он нафих не нужен - с тем же успехом для этого достаточно проанализировать LockedList.Connection.Connected.
  • Сергей М. © (13.10.11 09:55) [34]
    > Медвежонок Пятачок
    К тому же автор утверждает что 2-й клиент из 3-х активных отключился еще при царе горохе - аж час назад,- и в течение часа список контекстов якобы не уменьшился.. Якобы как был равен 3-м, так и остался .. А этого не м.б. если при отключении 2-го клиента на сервере гарантированно возникло и было успешно обработано событие OnDisconnect.

    Потому что


    procedure TIdContext.AfterRun;
    begin
     if Assigned(OnAfterRun) then begin
       OnAfterRun(Self);
     end;

     if FContextList <> nil then begin
       FContextList.Remove(Self);
     end;
    end;

  • Сергей М. © (13.10.11 10:06) [35]

    > требуется переодически сохранять данные о каждом юзере в
    > базу данных


    Непонятная вообще затея..

    Для каждого коннекта сервер в ходе его обслуживания возбуждает кучу всякоразных событий, в контексте обработки которых можно легко и без выкрутасов с общим списком коннектов отреагировать на изменение состояния контекста этого коннекта.
  • GekaNaz (13.10.11 10:13) [36]
    вот весь код который работает также... ничего не поменялось, исправил все что советовали, список юзеров вывел в отдельный листбокс, в мемо1 идет лог коннектов и дисконнектов с отображением имени клиента
    ЧТО ТУТ НЕ ТАК ?

    procedure TForm1.servConnect(AContext: TIdContext);
    begin
     memo1.Lines.Add('Connect='+Acontext.Connection.Socket.Binding.PeerIP);
     acontext.Data:=TmyData.Create;
     Tmydata(AContext.Data).logg:=false;
     Tmydata(AContext.Data).name:='-';
    end;

    procedure TForm1.servDisconnect(AContext: TIdContext);
    begin
     memo1.Lines.Add(Tmydata(AContext.Data).name+'   Disconnect='+Acontext.Connection.Socket.Binding.PeerIP+' / '+DateTimeToStr(now));
     Tmydata(AContext.Data).Free;
     AContext.Data:=nil;
    end;

    procedure TForm1.servCommandHandlers0Command(ASender: TIdCommand);
    begin
     q.SQL.Text:='select ID,XXX,B from client where nikname=:ni and pass=:pa';
     q.Params[0].Value:=asender.Params[0];
     q.Params[1].Value:=asender.Params[1];
     q.Open;
     if not q.Eof then
     begin  
       asender.Response.Add('USERDATA '+intToStr(Q.Fields[1].value)+' '+intToStr(q.Fields[2].value));
       Tmydata(asender.Context.Data).id:=Q.Fields[0].value;
       Tmydata(asender.Context.Data).xxx:=Q.Fields[1].value;
       Tmydata(asender.Context.Data).logg:=true;
       memo1.Lines.Add(asender.Params[0]+'    =   Login');
       Tmydata(asender.Context.Data).name:=asender.Params[0];
     end else
     begin// user not found
       asender.Response.Add('USERNULL 0');
     end;
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    var i,l,p,verrr:integer;
       f:double;
    begin
     lb1.items.Clear;
     if serv.Contexts <> nil then
     with serv.Contexts.LockList do try
     begin
       label1.Caption:=inttostr(count);  //здесь на форме смотрю сколько активных юзеров сейчас
       q.SQL.Text:='update client set XXX=:dd where id=:id;';
     if count>0 then
     for i:=0 to count-1 do
     begin
       if TIdContext(Items[i]).Connection.Connected then
       begin
        q.params[0].asinteger:=TMyData(TIdContext(Items[i]).Data).rur;
        q.params[1].asinteger:=TMyData(TIdContext(Items[i]).Data).id;
        q.ExecSQL;
                    lb1.Items.Add(TMyData(TIdContext(Items[i]).Data).name+' '+inttostr(q.params[0].asinteger));
       end else lb1.Items.Add('off '+TMyData(TIdContext(Items[i]).Data).name+' '+inttostr(q.params[0].asinteger));
     end;
     end;
     finally
       serv.Contexts.UnlockList;
     end;
     trans.Commit;//завершаем транзакцию
    end;
  • Сергей М. © (13.10.11 10:23) [37]
    Полные тексты протоколов приведи ..
  • GekaNaz (13.10.11 10:45) [38]
    LOGGIN username password  //команда авторизации
    QUIT  // disconnect

    :)  остальное пока не используется приводить смысла нет, да и остальной протокол еще в разработке
  • GekaNaz (13.10.11 10:47) [39]
    ответ на LOGGIN
    USERDATA xxx  // если авторизация успешна
    USERNULL 0   // если авторизация не прошла
 
Конференция "Сети" » список активных клиентов (Indy) [D7, WinXP]
Есть новые Нет новых   [134436   +21][b:0][p:0.001]