Список пользователей в чате

ArMellon

Guest
Список пользователей в чате

сделал чат на пхп, но есть одна проблема:
есть файл в котором храню
список пользователей находящихся в данный момент с чате такой строкой:
"ИмяЮзера|IDЮзера|Время последнего обновления фрейма юзера"
время последнего обновления нужно чтобы выявлять "пропавших" пользователей.
Так вот при кол-ве юзверей(10-15,обновление раз в 2 сек.для теста) чат начинает глючить,видимо слишком долго обрабатывается этот файл, чат начинает бешено писать Юзверь пропал/зашел.
flock использую.
ф-цию file заменил своей:
PHP:
function file_o($filename){
if (!file_exists($filename)) return null;
$fh=fopen($filename,'r');
flock($fh,LOCK_EX);
fseek($fh,0);
if (filesize($filename)>0){
 $result =explode("\n",fread($fh,filesize($filename)));
 if ($result[count($result)-1]=="")
  array_pop($result);
}
flock($fh,LOCK_UN);
fclose($fh);
return $result;
}
Что еще можно придумать?
использовать базу данных не получится.
 

Фанат

oncle terrible
Команда форума
это единственное место, где ты flock используешь?
 

ArMellon

Guest
Я думаю что описанный выше способ слишком тормозной, ведь при каждом обновлении фрейма пользователя происходит проход файла в цикле, разделение строки на userName,userId,userTime ф-цией explode.
И перезапись всего файла, для изменения userTime.
Если фрейм обновляется раз в 2 сек., а пользователей к примеру 20
то уже получается что файл должен переписываться 10 раз в сек.
что в реале не получается, и чат начинает жутко тормозить.
тем более что запросы ставятся в очередь...
чат начинает выкидывать пользователей по таймауту

-~{}~ 30.06.05 23:04:

подскажите как лучше решить проблему.....
 

Фанат

oncle terrible
Команда форума
Я думаю что описанный выше способ
думать от тебя не требуется.
от тебя требуется ответить на вопрос.
Если ты не заметил, то я тебя о чём-то спросил.
не отвечать, когда тебя спрашивают - это проявление невежливости.
Ты всего два сообщения написал, а уже решил вести себя невежливо. Куда это годится?
 

ArMellon

Guest
Автор оригинала: Фанат
думать от тебя не требуется.
от тебя требуется ответить на вопрос.
Если ты не заметил, то я тебя о чём-то спросил.
не отвечать, когда тебя спрашивают - это проявление невежливости.
Ты всего два сообщения написал, а уже решил вести себя невежливо. Куда это годится?
Извини конечно... я везде использовал flock
я уже немного переписал тот код, создав для каждого он-лайн пользователся свой файл со временем последнего обновления:
PHP:
function my_fileread($filename){
if (!file_exists($filename)){
 return false;
}
$fh=fopen($filename,"r");
flock($fh,LOCK_EX);
$res=fread($fh,filesize($filename));
fclose($fh);
return $res;
}
function my_filewrite($filename,$string){
$fh=fopen($filename,"a+");
flock($fh,LOCK_EX);
ftruncate($fh,0);
fwrite($fh,$string);
fclose($fh);
}
function on_line($name,$lastId){
$change=false;
$users=Array();
$id=my_fileread(ID_ONLINE_FILENAME);
//Считали последний ид
if (!file_exists(ONLINEDATAPATH.'/'.$_SESSION["myname"].'.dat')){
 addMsg('0','0','NEWUSER',$_SESSION["myname"],'0','system','0');
 my_filewrite(ID_ONLINE_FILENAME,mt_rand(1000,time()));
 $change=true;
}
my_filewrite(ONLINEDATAPATH.'/'.$_SESSION["myname"].'.dat',time());
//Записали таймштамп
$time=my_fileread('data/time.dat');
//Считали время последней проверки "Дохлых" ползователей
if ($id!=$lastid){
 $change=true;
}
if (((time()-$time)>120) or ($change)){
 //Пора проверить.Проходим он-лайн каталог
 if ($handle = opendir('./'.ONLINEDATAPATH)) {
  while (false !== ($file = readdir($handle))) {
   if ($file != "." && $file != "..") {
    $uTime=my_fileread(ONLINEDATAPATH.'/'.$file);
    if ((time()-$uTime)>120){
      unlink(ONLINEDATAPATH.'/'.$file);
      //гробим файл пользователя
             addMsg('0','0','OLDUSER',basename($file,".dat"),'timeout','system','0',time());
      $change=true;
     }else{
       $users[]=basename($file,".dat");
     }
     }
     }
     closedir($handle);
 }
 }
if ($change){
   my_filewrite(ID_ONLINE_FILENAME,mt_rand(1000,time()));
 $count=count($users);
 my_filewrite('data/time.dat',time());
 $id=my_fileread(ID_ONLINE_FILENAME);
   print "<SCRIPT LANGUAGE=\"JavaScript\">
         top.rF.dellishniy($count);\n";
   for ($i=0;$i<$count;$i++){
       print "top.rF.checkUsers('".$users[$i]."',$i,0);\n";
   }
   print "top.mF.uSz=$count;
          top.rF.inChat.innerHTML='Сейчас в чате:($count)';
          top.mF.uId=$id;\n</script>";
}
}
 

Фанат

oncle terrible
Команда форума
зачем тебе этот файл, если у тебя есть файл сессии?
 

ArMellon

Guest
Автор оригинала: Фанат
зачем тебе этот файл, если у тебя есть файл сессии?
мне же надо выявлять "дохлых" пользователей.
как ты себе представляешь без него сделать?
 

Фанат

oncle terrible
Команда форума
ты, наверное, не в курсе, что в большинстве продвинутых файловых систем у файла есть не только время модификации, но и время последнего доступа.
А при старте сессии пхп обращается к файлу сессии.
 

ArMellon

Guest
допустим один из пользователей вместо кнопки "выход" закрыл браузер крестиком вверху или свет у него погас или еще что.
Т.е. в данном случае он уже себя сам не удалит из он-лайн списка и будет так и болтаться в списке.
здесь же что происходит, запускается пхп скрипт вызванный из браузера <u>другого</u> пользователя, проходит в цикле список <u>всех</u> он-лайн пользователей и если время последнего обновления фрема у пользователя больше 2 мин, то удаляет его из списка.
И причем тут сессии?
 

Фанат

oncle terrible
Команда форума
при том, что файлы сессий можно хранить в указанном тобой каталоге.

кстати, не подскажешь, сколько времени выполняется запись файла с 20-ю пользователями?
 

ArMellon

Guest
не знаю...
думаю не долго.
дольше идет обработка списка пхп.
до дело не в этом, а втом что чат начинает глючить.
почему?
и как оптимизировать код чтобы работало нормально
что вы можете по коду приведенному выше сказать?
может действительно использовать один файл для всех?
 

Иван Шумков

Новичок
Фанат пытается вам сказать, чтобы вы перманентные данные о юзерах в сессии хранили, тогда никакие файлы не понадобятся.
 

Фанат

oncle terrible
Команда форума
не знаю...
думаю не долго.
дольше идет обработка списка пхп.
не подскажешь, сколько времени выполняется обработка пхп списка с 20-ю пользователями?

как оптимизировать код
чувак.
оптимиация - это ускорение.
чтобы что-то ускорить - надо знать, что именно торморзит. А ты не знаешь.
Ты полагаешь, видимо, что у читателей форума есть в голове пхп интерпретатор, и они при одном азгляде на код сразу определяют, гда надо оптимизировать.
Очень жаль тебя расстраивать, но это не так, к сожалению.
Поэтому тебе придётся уж самому как-нибудь расстараться.
Здесь тебя ждёт ещё одно разочарование. Форум - не салон высшей магии. Куда ты подтаскиваешь свой код, а тебе тычут пальцем в него и говорят - проблема ЗДЕСЬ!
С кодом твоим, кроме тебя, никто возиться не будет.
На форуме могут только развеять дурацкие заблуждения и помочь встать на путь истинный.

Поэтому.
Если ты, весь из себя такой умный, полагаешь, что обработка десятка строк на пхп занимает какие-то нереальные объемы времени, тебя никто переубеждать не будет. Тебе на форуме просто скажут: возьми функцию microtime() замерь время до обработки, после обработки, и вычти первое из второго.
Например, так:
$start_timer=microtime();

тут твой код, скорость выполнения которого надо измерить

list($s,$ms)=explode(" ",$start_timer);
$start=$s+$ms;
list($s,$ms)=explode(" ",microtime());
echo round($s+$ms-$start,3).' sec.';

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

-~{}~ 01.07.05 08:47:

Иван Шумков
Ничего такого я не пытаюсь сказать.
Для того, чтобы посчитать юзеров онлайт, в сессии ничего хранить не нужно. Нужны просто сами файлы сессий.
 

ArMellon

Guest
Ладно, вы можеше дать рабочий пример реализации этой задачи?
 
Сверху