Конференция "Сети" » список активных клиентов (Indy) [D7, WinXP]
 
  • GekaNaz (12.10.11 20:32) [0]
    Спасайте люди добрые :)
    пишу клиент-серверное приложение, клиенты общаются с сервером нормально, но требуется переодически сохранять данные о каждом юзере в базу данных,
    проблема в следующем- по таймеру 4 раза в минуту выполняется код:
     list:=serv.Contexts.LockList;
     for i:=0 to list.count-1 do
     begin
       q.SQL.Text:='update ClientTable set XXX=:dd where id=:id;';
       q.params[0].asinteger:=TMyData(TIdContext(List.Items[i]).Data).xxx;
       q.params[1].asinteger:=TMyData(TIdContext(List.Items[i]).Data).id;
       q.ExecSQL;
     end;
     serv.Contexts.UnlockList;

    это работает если клиент один.... или подключился второй.. третий и т.д... до тех пор пока один из них не отключится. свойство count выдает непонятное число .. оно иногда не меняется при отключении юзера, просто connection помечается как неактивное.
     А иногда при отключении второго юзера (из трех) count становится равным 2, а третий юзер на второе место не передвигается... и моя процедура по таймеру пытается постоянно писать в базу данных данные про неактивного второго юзера, а про третьего забывает..
  • Сергей М. © (12.10.11 20:51) [1]

    > xxx


    А это что за порно ?
  • Gekanaz (12.10.11 20:57) [2]
    есть блок данных в который записывается id из базы данных о приконнекченом юзере и еще некоторая инфа.... эта инфа переодически меняется клиентским соединением.... и её надо переодически сохранять в базу данных ... если вы знаете более интересный способ, то предложите
  • Gekanaz (12.10.11 20:59) [3]
    этот блок данных сохраняется в памяти (структура TMyData) у каждого нового коннекта есть указатель на данные  items[i].Data.. вот эти данные в цикле и надо сохранять, так как они очень важные , и ждать, пока клиент через пару дней отвалится... и по дисконнекту сохранять данные не логично...
  • Сергей М. © (12.10.11 21:00) [4]

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


    С чего он передвинется-то, если ты сделал LockList списку коннектов ?
  • Gekanaz (12.10.11 21:08) [5]
    да нет, вы меня не поняли... клиент отключается гораздо раньше чем возникает эта процедура по таймеру, ставил таймер .. раз в 60 секунд.. все равно непонятки возникают. а как бы вы посоветовали считать данные о всех активных подключениях ?
  • Сергей М. © (12.10.11 21:10) [6]

    > клиент отключается


    А как этот фиксирует твой сервер ?
  • Gekanaz (12.10.11 21:11) [7]
    в обработчике ондисконнект  я вывожу в лог кто отключился... и больше ничего не делаю.. может в этом и ошибка
  • Gekanaz (12.10.11 21:15) [8]
    еще при отключении юзера нужно в базу данных сохранить последние актуальные данные, тут надо использовать походу пул коннектов к базе данных, это я еще пока незнаю как сделать
  • Сергей М. © (12.10.11 21:36) [9]
    > третий юзер на второе место не передвигается

    Чкм это подтверждается ?
  • Gekanaz (12.10.11 21:39) [10]
    в этом же цикле я добавляю имя клиента в Memo .. и вижу то, что выводится только первый и второй, который уже отключился... а до третьего дело не доходит, так как count уже=2
  • Gekanaz (12.10.11 21:42) [11]
    memo1.lines.clear;
    q.SQL.Text:='update ClientTable set XXX=:dd where id=:id;';//вынес из цикла

    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(q.params[0].asinteger);
    end;
  • Сергей М. © (12.10.11 21:44) [12]
    А оно, это имя, откуда берется ?
    Из данных, ссылка на которые ты хранишь в Data ?
    Тогда это значит что данные об "имени" клиента не соответствуют действительности
  • Gekanaz (12.10.11 21:46) [13]
    именно там и храню, а где их хранить ?? когда создается подключение создается нить... к ней прикрепляется кусок данных, я создаю экземпляр в памяти.. и храню там данные.. когда происходит дисконнект , я очищаю память
  • Gekanaz (12.10.11 21:48) [14]
    TMyData = class //индивидуальные данные каждого коннекта
     public
       id:integer;//
       logg:boolean;//
       xxx : integer;
       Name : string;
     end;
  • Сергей М. © (12.10.11 21:49) [15]

    > когда создается подключение создается нить


    На сервере только что случился факт подключения, клиент еще НИЧЕГО не сказал серверу, а сервер уже знает имя клиента ?
    Чудеса)..
  • Gekanaz (12.10.11 21:54) [16]
    procedure TForm1.servConnect(AContext: TIdContext);
    begin
     memo1.Lines.Add('Connect='+Acontext.Connection.Socket.Binding.PeerIP+' \ '+DateTimeToStr(now));
     acontext.Data:=TmyData.Create;
     Tmydata(AContext.Data).logg:=false;
     Tmydata(AContext.Data).name:='еще не авторизован';
    end;

    procedure TForm1.servDisconnect(AContext: TIdContext);
    begin
      memo1.Lines.Add('Disconnect='+Acontext.Connection.Socket.Host);
    end;

    это две процедуры когда клиент коннектится, и отключается соответсвенно... в дисконнекте экземпляр данных не уничтожаю.. порылся в исходниках ,. вроде компонента сама удаляет экземпляр данных если он существует (  serv: TIdCmdTCPServer;)
  • Gekanaz (12.10.11 21:55) [17]
    нет, авторизация происходит следом за коннектом.. если такого юзера нет.. сразу отключение
  • Gekanaz (12.10.11 21:58) [18]
    это обработка команды сервера logging user password

    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('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 21:59) [19]

    > в дисконнекте экземпляр данных не уничтожаю.. порылся в
    > исходниках ,. вроде компонента сама удаляет экземпляр данных
    > если он существует


    Как это "сама удаляет" ?
    Св-во Data - это нетипизированный указатель, откуда серверу знать что за ним кроется и как это "удалять" ?
 
Конференция "Сети" » список активных клиентов (Indy) [D7, WinXP]
Есть новые Нет новых   [134435   +20][b:0][p:0.001]