Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.01 c
4-1116486705
JB
2005-05-19 11:11
2005.07.25
Список процессов


14-1120313377
lookin
2005-07-02 18:09
2005.07.25
Правила хорошего тона


14-1120210615
Rentgen
2005-07-01 13:36
2005.07.25
Длина кабеля LCD to IBM


14-1120131748
Иксик
2005-06-30 15:42
2005.07.25
Можно ли переоформлять билеты на поезд на Украине?


8-1111865107
seregka
2005-03-26 22:25
2005.07.25
TMemoryStream и bitmap





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский