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

Обсуждение в разделе «PHP, PERL, MySQL, JavaScript», начал(-а) barnaki, 6.01.2012.

  1. barnaki

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

    Регистрация:
    2.11.2008
    Сообщения:
    642
    Одобрения:
    73
    Репутация:
    2
    подскажите грамотный алгоритм как на php,javascript реализовать пользователей онлайн в соц сети. пока думаю только по таймауту на java ajax запрос посылать. но это не вариант . может кто делал
     
  2. -=Zhenek=-

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

    Регистрация:
    31.12.2007
    Сообщения:
    425
    Одобрения:
    73
    Репутация:
    1
    Я для чата делал но тоже запросом.
    Была база с сессиями. и там постоянно обновлялось время активности. если оно например больше 30 то пишем что офф.

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

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

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

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

    randman Members of Antichat

    Регистрация:
    15.05.2010
    Сообщения:
    1 372
    Одобрения:
    604
    Репутация:
    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 - Старейшина

    Регистрация:
    2.11.2008
    Сообщения:
    642
    Одобрения:
    73
    Репутация:
    2
    вот и я говорю ajax. но на сервере что ? ведь нехилая нагрузка я так подумал. какой скрипт бы оптимальнее работал на сервере ? к примеру что работать будет быстрее Mysql или memcache.
    2 -=Zhenek=-. а как ты в чате делал появление чужих сообщений ? тоже ajax ?
     
    #4 barnaki, 6.01.2012
    В последний раз редактировалось: 6.01.2012
  5. -=Zhenek=-

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

    Регистрация:
    31.12.2007
    Сообщения:
    425
    Одобрения:
    73
    Репутация:
    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 пользователь.
  6. Sharky

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    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

    Регистрация:
    25.04.2008
    Сообщения:
    2 497
    Одобрения:
    808
    Репутация:
    614
    Sharky Вы действительно думаете, что постановка файловой системы в раскорячку - это хорошая идея?
     
    _________________________
  8. Sharky

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    46
    нет) но я думаю в их случае не те нагрузки когда стоило бы об этом беспокоиться
     
  9. AnGeI

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

    Регистрация:
    8.12.2008
    Сообщения:
    457
    Одобрения:
    80
    Репутация:
    16
    Так как все-таки лучше? :)
     
  10. Sharky

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    46
    лучше чтоб работало...а дальше зависит от потребностей...платите деньги и я ещё 10 вариантов придумаю и напишу
     
  11. -=Zhenek=-

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

    Регистрация:
    31.12.2007
    Сообщения:
    425
    Одобрения:
    73
    Репутация:
    1
    Sharky

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

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

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

    Isis Мафиозя //хекед :D

    Регистрация:
    20.11.2006
    Сообщения:
    3 484
    Одобрения:
    1 193
    Репутация:
    241
    Что же вы так боитесь выполнять запросы к базе.
     
  13. Sharky

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    46
    ок..раз умный такой то при каждой проверки даты создания файла если она больше лайфтайма то удаляй файл сессии...так они не накопятся...зануда

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

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

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


    ещё вопросы?
     
    #13 Sharky, 8.01.2012
    В последний раз редактировалось модератором: 8.01.2012
  14. Gifts

    Gifts Green member

    Регистрация:
    25.04.2008
    Сообщения:
    2 497
    Одобрения:
    808
    Репутация:
    614
    Sharky это не решения, это защита костыля десятком других костылей и поиск самого хитрого способа завестить систему или добавить зависимостей
     
    _________________________
    Это одобряет 1 пользователь.
  15. Sharky

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    46
    окей) жду твоего решения)
     
  16. Gifts

    Gifts Green member

    Регистрация:
    25.04.2008
    Сообщения:
    2 497
    Одобрения:
    808
    Репутация:
    614
    Sharky как вы выразились - простое решение самое эффективное. И когда говорят простое - то гланды удаляют через рот.

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

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

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

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

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

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

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    46
    ты перечислил ровно половину моих варантов)
     
  18. Gifts

    Gifts Green member

    Регистрация:
    25.04.2008
    Сообщения:
    2 497
    Одобрения:
    808
    Репутация:
    614
    Sharky покажите цитатами, пожалуйста, что вы подразумеваете
     
    _________________________
  19. Sharky

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

    Регистрация:
    1.05.2006
    Сообщения:
    749
    Одобрения:
    312
    Репутация:
    46
    2 Gifts
     
    Это одобряет 1 пользователь.
  20. barnaki

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

    Регистрация:
    2.11.2008
    Сообщения:
    642
    Одобрения:
    73
    Репутация:
    2
    . нет нагрузки ожидаются серьезные. хочется верить по крайней мере.
    таких решений не предлогать. базу подкючать ради онлайн пользователей это жесть.
    .
    memcache думаю заюзаю. и все же вопрос. что будет быстрее работать.
    надо протестить что быстрее memcache или mysql
     
    #20 barnaki, 11.01.2012
    В последний раз редактировалось: 11.01.2012
Загрузка...