php javascript пользователи онлайн.

Discussion in 'PHP' started by barnaki, 6 Jan 2012.

  1. barnaki

    barnaki Elder - Старейшина

    Joined:
    2 Nov 2008
    Messages:
    676
    Likes Received:
    140
    Reputations:
    4
    подскажите грамотный алгоритм как на php,javascript реализовать пользователей онлайн в соц сети. пока думаю только по таймауту на java ajax запрос посылать. но это не вариант . может кто делал
     
  2. -=Zhenek=-

    -=Zhenek=- Elder - Старейшина

    Joined:
    31 Dec 2007
    Messages:
    271
    Likes Received:
    77
    Reputations:
    1
    Я для чата делал но тоже запросом.
    Была база с сессиями. и там постоянно обновлялось время активности. если оно например больше 30 то пишем что офф.

    Правда запросов много выходит...

    Вконтакте вроде раз в минуты 2 проверяет (т.к после выхода ты долго онлайн) но у них своя БД заточенная под это.

    Можно при переходе по страницам обновлять, но если он будет смотреть фильм то уйдет в офф. значит только аякс.

    Можно что-то типа раз в минуту проверять и не в базу а скриптом в фаил писать, а крон раз в 2 минуты будет фаил парсить и одним запросом обновлять всех.
     
  3. randman

    randman Members of Antichat

    Joined:
    15 May 2010
    Messages:
    1,366
    Likes Received:
    610
    Reputations:
    1,101
    Ну если считать время последнего запроса - что будет ещё неточнее.

    Примерно так:
    PHP:
    function online () {
        $.
    ajax({
            
    url:      '/online.php',
            
    type:      'post',
            
    cache:    false,
            
    data:      'json={"online":true}',
            
    success:  function(response){
                    
    alert('Обновление статуса прошло успешно.');
                },
            
    error:  function(xhrstr){
                    
    alert('Обновление статуса прошло успешно.');
            }
        });

    };

    $(function() {
        
    setInterval(function() {
            
    online();
        }, 
    5000);
    }); 


     
  4. barnaki

    barnaki Elder - Старейшина

    Joined:
    2 Nov 2008
    Messages:
    676
    Likes Received:
    140
    Reputations:
    4
    вот и я говорю ajax. но на сервере что ? ведь нехилая нагрузка я так подумал. какой скрипт бы оптимальнее работал на сервере ? к примеру что работать будет быстрее Mysql или memcache.
    2 -=Zhenek=-. а как ты в чате делал появление чужих сообщений ? тоже ajax ?
     
    #4 barnaki, 6 Jan 2012
    Last edited: 6 Jan 2012
  5. -=Zhenek=-

    -=Zhenek=- Elder - Старейшина

    Joined:
    31 Dec 2007
    Messages:
    271
    Likes Received:
    77
    Reputations:
    1
    Все сообщения и свои и чужие выводились с интервалом (10,15,20) секунд на выбор пользователя в настройках.
    Это конечно дает ощутимую нагрузку, но на то он и чат.
    Я с каждым запросом еще кроме самих сообщений получал в переменную ИД последнего полученного сообщения. И уже каждый следующий запрос не ворошил всю базу,а просто делал проверку есть ли новые сообщения после допустим сообщения с ИД 152.


    Ну тебе нужно избавиться от большого количества запросов.
    Допустим онлайн пользователи хранятся в базе :

    login|timestamp

    при проверки онлайн человек или нет достаточно из текущего тайстампа вычесть тот что в базе. Если например он больше 120 (2 минуты) то считаем что пользователь ОФФ.

    При обновлении статуса просто перезаписываем у этого логина тайстамп на текущий.

    Поэтому аякс может посылать запрос к файлу который например будет записывать в фаил(дописывать в конец) просто логин там через разделитель |
    user1|user2|user3
    Крон раз в минуту будет парсить этот фаил в массив, удалять дубликаты и делать 1 запрос типа UPDATE online SET timestamp='$time' WHERE login in (".implode(",",$users).")
    Где $users массив с пользователями а $time текущий time();

    Получится что раз в 1-2 минуты все пользователи кто онлайн буду онлайн.
    Нужно только следить чтоб проверка на разницу таймстампов была чуть больше времени выполнения крона.

    п.с Это личное мнение. Это уменьшит кол-во запросов, но как быстро и удобно использовать файловую систему. Почитай архитектуру вконтакте,фейсбука. Посмотри их таймауты и т.д последи. Скачай исходник соцсети и глянь как там реализованно.
     
    1 person likes this.
  6. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    господи какие вы извращенцы..мыслите проще...пусть как извращенцы конченые, но проще..как я

    и так...первое...сессии нахуя придумали? правильно...чтоб хранить в них всякое говно...но мы именно по ним будем определять онлайн

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

    PHP:
    ini_set('session.gc_maxlifetime'60); // время жизни раз
    ini_set('session.cookie_lifetime',     60); //время жизни два
    ini_set('session.save_path'$_SERVER['DOCUMENT_ROOT'] .'../sessions/'); //соаздаем в корне папку sessions, без этой строки не менялось время жизни сессии
    session_start(); //стартуем
    раз в 60 секунд для каждого пользователя будет создаваться файл сессии, если хотите в нем что-то хранить то делаете как всегда при работе с сессиями

    Пример хранения IP пользователя (добавляется после старта сессии)
    PHP:
    $_SESSION['user_ip'] = $_SERVER['REMOTE_ADDR'];
    Ну а дальше собственно проверка количества активных сессий (те которые созданы менее 60 секунд назад)

    PHP:
    function get_online(){
        
    clearstatcache(); //Очищает кэш состояния файлов
        
    $sess_dir session_save_path(); //узнаем папку хранения файлов сессий
        
    $lifetime 10//наше время жизни сессии которое указывали в самом начале
        /*Ну дальше построчно не буду расписывать, там просто считываем папку и проверяем в ней количество файлов созданных менее 60 секунд назад */
        
    if ($path scandir ($sess_dir)){
            
    $count count ($path);
            
    $users 0;
            for (
    $i 2$i $count$i++){
                if (
    time() - fileatime ($sess_dir '/' $path[$i]) < $lifetime){
                    
    $users++;
                }
            }
                                
            return 
    $users;
        } else {
            return 
    'error';
        }
    }
    PHP:
    #with love by Sharky
     
  7. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    Sharky Вы действительно думаете, что постановка файловой системы в раскорячку - это хорошая идея?
     
    _________________________
  8. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    нет) но я думаю в их случае не те нагрузки когда стоило бы об этом беспокоиться
     
  9. AnGeI

    AnGeI Elder - Старейшина

    Joined:
    8 Dec 2008
    Messages:
    395
    Likes Received:
    79
    Reputations:
    16
    Так как все-таки лучше? :)
     
  10. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    лучше чтоб работало...а дальше зависит от потребностей...платите деньги и я ещё 10 вариантов придумаю и напишу
     
  11. -=Zhenek=-

    -=Zhenek=- Elder - Старейшина

    Joined:
    31 Dec 2007
    Messages:
    271
    Likes Received:
    77
    Reputations:
    1
    Sharky

    Допустим у меня 20 друзей и мне нужно узнать кто из них онлайн...
    Перебирать все файлы сессий? Даже при 400к записей это будет капец.

    Оо ну конечно) Отрежте себе ногу, главное чтоб выжили. =)

    Делать надо сразу как лучше,удобнее, чем потом при увеличении нагрузки не переписывать все. Семь раз как говорится..
     
  12. banned

    banned Banned

    Joined:
    20 Nov 2006
    Messages:
    3,324
    Likes Received:
    1,193
    Reputations:
    252
    Что же вы так боитесь выполнять запросы к базе.
     
  13. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    ок..раз умный такой то при каждой проверки даты создания файла если она больше лайфтайма то удаляй файл сессии...так они не накопятся...зануда

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

    или вернись к файлам...но не родным сессиям и копай литературу про бинарный поиск

    то возьми какую нереляционную бд типа redis или любую платформу для кэширования данных....вобщем то что позволяет хранить данные в оперативе...и вперед...дальше думаю тоже поймешь


    ещё вопросы?
     
    #13 Sharky, 8 Jan 2012
    Last edited by a moderator: 8 Jan 2012
  14. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    Sharky это не решения, это защита костыля десятком других костылей и поиск самого хитрого способа завестить систему или добавить зависимостей
     
    _________________________
    1 person likes this.
  15. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    окей) жду твоего решения)
     
  16. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    Sharky как вы выразились - простое решение самое эффективное. И когда говорят простое - то гланды удаляют через рот.

    1) Понять, что никому не нужно знать с точностью до 5 секунд открыта у тебя страница соц.сети или нет. Важно знать, что ты совершаешь активные действия, а именно - просмотр страниц пользователей, постинг сообщений, еще что-то в зависимости от предметной области

    2) Завести (как предложил -=Zhenek=-) столбец timestamp и, действительно, лучше в отдельной таблице. Делать один запрос на апдейт при просмотре страниц пользователей и добавить триггер базы данных на запрос UPDATE к таблицам с сообщениями и прочему

    3) Выборку последнего времени осуществлять простым JOIN по двум-трем таблицам.

    4) Не забывать что используется реляционная база данных и правильно расставить индексы и делать ПРАВИЛЬНЫЕ запросы по таблицам

    Естественно, выборку из БД лучше кешировать (но опять таки, без экзотики, memcached более чем достаточно), благо ТС знает ZendFramework там, вроде как, это реализовано достаточно прозрачно.

    Мне кажется этот подход абсолютно очевидным, если вы не первый день программируете, нет?
     
    _________________________
    1 person likes this.
  17. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    ты перечислил ровно половину моих варантов)
     
  18. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    Sharky покажите цитатами, пожалуйста, что вы подразумеваете
     
    _________________________
  19. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    2 Gifts
     
    1 person likes this.
  20. barnaki

    barnaki Elder - Старейшина

    Joined:
    2 Nov 2008
    Messages:
    676
    Likes Received:
    140
    Reputations:
    4
    . нет нагрузки ожидаются серьезные. хочется верить по крайней мере.
    таких решений не предлогать. базу подкючать ради онлайн пользователей это жесть.
    .
    memcache думаю заюзаю. и все же вопрос. что будет быстрее работать.
    надо протестить что быстрее memcache или mysql
     
    #20 barnaki, 11 Jan 2012
    Last edited: 11 Jan 2012