Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.25;
Скачать: CL | DM;

Вниз

Список юзверей в чате   Найти похожие ветки 

 
ArMellon ©   (2005-06-30 21:55) [0]

сделал чат на пхп, но есть одна проблема:
есть файл в котором храню
список пользователей находящихся в данный момент с чате такой строкой:
"ИмяЮзера|IDЮзера|Время последнего обновления фрейма юзера"
время последнего обновления нужно чтобы выявлять "пропавших" пользователей.
Так вот при кол-ве юзверей(10-15,обновление раз в 2 сек.для теста) чат начинает глючить,видимо слишком долго обрабатывается этот файл, чат начинает бешено писать Юзверь пропал/зашел.
flock использую.
ф-цию file заменил своей:
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;
}

Что еще можно придумать?
использовать базу данных не получится.


 
VictorT ©   (2005-06-30 22:20) [1]

Это чтение, а запись?


 
VictorT ©   (2005-06-30 22:22) [2]

З.Ы. Имхо, при чтении можно вообще не блокировать, а только при записи.


 
ArMellon ©   (2005-06-30 22:41) [3]

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


 
ArMellon ©   (2005-06-30 23:04) [4]

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


 
VictorT ©   (2005-06-30 23:15) [5]


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

Покажи код, посмотрим, что можно соптимизировать.
Кроме того, я думаю, от одного из параметров (userName или userId) можно отказаться.


 
Ломброзо ©   (2005-06-30 23:16) [6]

ArMellon ©   (30.06.05 23:04)
подскажите как лучше решить проблему.....


переписать используя pipes или другие способы межпроцесскоммуникации. Чего бы спейсок в памяти не держать? Общего хэшмапа хватило бы за глаза и за уши. Или berkley db-файла. Возьмите Perl, он это умеет.

--------
DMJS 0.6 | http://dmjsclient.narod.ru


 
VictorT ©   (2005-06-30 23:24) [7]

Кстати, этот код:
$result =explode("\n",fread($fh,filesize($filename)));
можно заменить таким:
$result = readfile($filename);


 
VictorT ©   (2005-06-30 23:25) [8]


> Чего бы спейсок в памяти не держать?

Ух ты, я про такое и не слышал. Где можно прочитать?


 
ArMellon ©   (2005-06-30 23:33) [9]

я уже немного переписал тот код, создав для каждого он-лайн пользователся свой файл со временем последнего обновления:

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>";
}
}


 
ArMellon ©   (2005-06-30 23:35) [10]

можно заменить таким:
$result = readfile($filename);


т.е. заменить?
мне надо вернуть массив строк, а так вернет просто строку


 
VictorT ©   (2005-06-30 23:38) [11]


> мне надо вернуть массив строк, а так вернет просто
> строку

именно, readfile возвращает массив. Глянь в мануале.


 
Ломброзо ©   (2005-06-30 23:39) [12]

VictorT ©   (30.06.05 23:25)

> Чего бы спейсок в памяти не держать?

Ух ты, я про такое и не слышал. Где можно прочитать?


Ой. Это в книжке по Perl есть, с бараном или верблюдом. Я перл уже года два как в руках не держал.
Межпроцессное взаимодействие включает в себя сигналы, файлы, каналы (именованные и неименованные), и сокеты. Именованный канал в Unix - это что-то вроде файла в памяти, использующий FIFO.
Далее, из файлов можно использовать Berkley DB - это просто потокобезопасный хэш на диске. Поскольку хэш - скорость чтения выше скорости записи, но для 10-15 пользователей эта разница будет незаметна.

Кроме того, в Java существуют т.н. сервлеты, то есть некие классы, обрабатывающие http-запросы и существующие в контексте контейнера сервлетов (грубо говоря, веб-сервера). Сервлет можно реализовать таким образом, что он будет использовать static-переменные, поэтому независимо от количества одновременно исполняемых сервлетов, все они могут совместно использовать общую переменную. Наверняка подобный механизм можно реализовать для PHP или Perl, если скрипты выполняются в контексте веб-сервера, а не как CGI.


 
VictorT ©   (2005-06-30 23:40) [13]


> создав для каждого он-лайн пользователся свой файл со
> временем последнего обновления:

Не кажется мне, что так лучше.


 
ArMellon ©   (2005-06-30 23:43) [14]

по поводу readfile
http://airbase.ru/computers/php/flock/
Следует также помнить, что читать файл нужно только через fopen() (можно fopen(..","r")) НО НЕ ЧЕРЕЗ file() или readfile(). Может считаться полузаписанный файл. Т.е. если это только для разового чтения и сбой не страшен, то пожалуйста. Если же требуется что-то прочитать, изменить и записать, то всё надо делать в одно открытие файла, как в приведённом выше примере.


 
ArMellon ©   (2005-06-30 23:50) [15]

Не кажется мне, что так лучше.

а как лучше?


 
АНТИСПАММЕР   (2005-07-01 01:10) [16]

А может лучше таблицу mySQL использовать ?
У иеня не глючило


 
ArMellon ©   (2005-07-01 01:16) [17]

мля...
я на бесплатном хостинге сижу, там mysql не дают или вы можете мне нормальный бесплатный хостинг с ней посоветовать?


 
Nik8. ©   (2005-07-01 04:47) [18]

Зделай как в моем чате, отдавай юзеров только когда crc не совпадает.
+


 
Nik8. ©   (2005-07-01 04:54) [19]

Сделай как в моем чате, отдавай юзеров только когда crc не совпадает.
+ Передавай в запросе на обновление пользователей размер файла(как сдесь), и сравнивай в скрипте.



Страницы: 1 вся ветка

Текущий архив: 2005.07.25;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.031 c
1-1120829932
Vudu
2005-07-08 17:38
2005.07.25
Что за сообщение?


10-1097502395
Roobee
2004-10-11 17:46
2005.07.25
Интеграция Delphi и Excel. Мастера откликнитесь.


1-1120774022
Brack
2005-07-08 02:07
2005.07.25
Как можно сделать TLabel прозрачным?


1-1120322132
Brack
2005-07-02 20:35
2005.07.25
Как двигать обьекты?


14-1120151731
kaif
2005-06-30 21:15
2005.07.25
Должен ли гурман жарить на тефлоне?