Форум: "Потрепаться";
Текущий архив: 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