Статьи

Heartbeat API: использование Heartbeat в плагине

В этом уроке мы собираемся создать простой плагин, который использует Heartbeat API. Наш плагин будет оповещать пользователей, вошедших в систему, через похожие на рычание уведомления, когда другой пользователь входит в систему или выходит из нее.

Поскольку этот урок посвящен API-интерфейсу Heartbeat, я опущу детали создания заголовка плагина или структуры файла: плагин очень прост, и вы можете полностью изучить исходный код в этом репозитории GitHub .

Пользователь будет считаться «вошедшим в систему», когда он войдет в систему и будет активным в течение последних 24 часов. Если пользователь выходит из системы или неактивен в течение 24 часов, он считается отключенным от сети. Мы будем следить за статусом пользователя «онлайн» и «последней активной» отметкой времени, чтобы определить, кто в данный момент онлайн.


Сначала мы создадим пару функций, подключенных к wp_login и wp_logout . Они запускаются, когда пользователь входит / выходит из WordPress. Когда пользователь входит в систему, мы обновляем его статус входа (сохраненный как пользовательская мета) на «true» и обновляем его последнюю активную временную метку.

1
2
3
4
5
function whoisonline_logged_in( $username, $user ) {
    update_user_meta( $user->ID, ‘whoisonline_is_online’, true );
    update_user_meta( $user->ID, ‘whoisonline_last_active’, time() );
}
add_action( ‘wp_login’, ‘whoisonline_logged_in’, 10, 2 );

Аналогичным образом, когда пользователь выходит из системы, мы обновляем его статус в сети на false:

1
2
3
4
5
function whoisonline_logged_out() {
    $user_id = get_current_user_id();
    update_user_meta( $user_id, ‘whoisonline_is_online’, false );
}
add_action( ‘wp_logout’, ‘whoisonline_logged_out’ );

Теперь давайте создадим функцию, которая возвращает массив имен пользователей активных пользователей, проиндексированных по идентификатору пользователя. Мы будем использовать get_users() для запроса всех пользователей, которые были активны в течение последних 24 часов (используя мета-ключ whoisonline_last_active ).

Затем мы whoisonline_is_online от всех пользователей, которые вышли из системы, проверив whoisonline_is_online пользователя / метаданные whoisonline_is_online .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function who_is_online( $args = array() ) {
 
    // Get users active in last 24 hours
    $args = wp_parse_args( $args, array(
        ‘meta_key’ => ‘whoisonline_last_active’,
        ‘meta_value’ => time() — 24 * 60 * 60,
        ‘meta_compare’ => ‘>’,
        ‘count_total’ => false,
    ) );
 
    $users = get_users( $args );
 
    // Initiate array
    $online_users = array();
 
    foreach ( $users as $user ) {
        if ( ! get_user_meta( $user->ID, ‘whoisonline_is_online’, true ) )
            continue;
 
        $online_users[$user->ID] = $user->user_login;
    }
 
    return $online_users;
}

Прежде чем мы рассмотрим клиентскую часть Heaertbeat API, давайте разберемся с ответом сервера на запрос «кто в сети». Как было описано в первой части этой серии , мы подключим фильтр heartbeat_received (нам не нужно его запускать для пользователей, вышедших из системы, поэтому мы не будем использовать фильтр heartbeat_nopriv_received ).

Сначала мы обновим отметку времени активности текущего пользователя и убедимся, что его статус установлен на «онлайн». Далее мы проверим, что был сделан запрос на данные «кто онлайн», who-is-online ключ « who-is-online (который мы будем использовать позже) в полученных $data .

Если это так, мы ответим массивом зарегистрированных пользователей в форме:

1
array( [User ID] => [User log in] )

Как возвращено who_is_online() .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
function whoisonline_check_who_is_online( $response, $data, $screen_id ) {
 
    // Update user’s activity
    $user_id = get_current_user_id();
    update_user_meta( $user_id, ‘whoisonline_last_active’, time() );
    update_user_meta( $user_id, ‘whoisonline_is_online’, true );
 
    // Check to see if «who’s online?»
    if ( ! empty( $data[‘who-is-online’] ) ) {
 
        // Attach data to be sent
        $response[‘whoisonline’] = who_is_online();
 
    }
 
    return $response;
}
add_filter( ‘heartbeat_received’, ‘whoisonline_check_who_is_online’, 10, 3 );
add_filter( ‘heartbeat_received’, ‘whoisonline_check_who_is_online’, 10, 3 );

Теперь создайте файл JavaScript who-is-online.js в корне папки вашего плагина. Ниже приведен план файла.

Сначала мы инициируем нашу глобальную переменную whoisonline . whoisonline.online и whoisonline.onlinePrev являются «ассоциативными массивами» (строго говоря, с точки зрения JavaScript, они являются объектами) имен пользователей, проиндексированных по идентификатору пользователя, что соответствует тем пользователям, которые находятся «в сети» в текущем / предыдущем бить. Это используется для определения того, когда пользователь вошел в систему или вышел из нее.

Затем мы инициируем наш запрос данных о том, кто в сети, с помощью wp.heartbeat.enqueue и прослушиваем ответ, связывая обратный вызов с событием heartbeat-tick.whoisonline . В этом обратном вызове мы проверяем данные, возвращаемые сервером, выполняем все необходимые действия и затем проверяем, что наш запрос данных ставится в очередь для следующего удара.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
// Inititate variables
var whoisonline = { online: false, onlinePrev: false };
 
jQuery(document).ready(function() {
 
    //Set initial beat to fast — for demonstrative purposes only!
    wp.heartbeat.interval( ‘fast’ );
 
    //Enqueue are data
    wp.heartbeat.enqueue( ‘who-is-online’, ‘whoisonline’, false );
 
    jQuery(document).on( ‘heartbeat-tick.whoisonline’, function( event, data, textStatus, jqXHR ) {
        if ( data.hasOwnProperty( ‘whoisonline’ ) ) {
            // Perform actions with returned data
        }
 
        // In our example, we want to attach data for the next beat.
        // This might not be in the case in all applications: only queue data when you need to.
        wp.heartbeat.enqueue( ‘who-is-online’, ‘whoisonline’, false );
    });
});

Теперь давайте заполним детали логики внутри нашего обратного вызова heartbeat-tick.whoisonline . Всякий раз, когда данные поступают с сервера, мы сначала проверяем, что они содержат массив вошедших в систему пользователей (который задается ключом ‘whoisonline’), проверяя data.hasOwnProperty( 'whoisonline' ) . Если так…

  • Обновите whoisonline.onlinePrev чтобы отразить, кто был в сети в последний момент, и whoisonline.online чтобы отразить, кто был в сети в текущий период.
  • Проверьте идентификаторы пользователей, которые отображаются в whoisonline.online , но отсутствуют в whoisonline.onlinePrev . Эти пользователи только что вошли в систему.
  • Проверьте идентификаторы пользователей, которые отображаются в whoisonline.onlinePrev , но отсутствуют в whoisonline.online . Эти пользователи только что вышли из системы.

Готовый файл JavaScript выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var whoisonline = { online: false, onlinePrev: false };
 
jQuery(document).ready(function() {
 
    // Set initial beat to fast
    wp.heartbeat.interval( ‘fast’ );
 
    // Enqueue are data
    wp.heartbeat.enqueue( ‘who-is-online’, ‘whoisonline’, false );
 
    jQuery(document).on( ‘heartbeat-tick.whoisonline’, function( event, data, textStatus, jqXHR ) {
 
        if ( data.hasOwnProperty( ‘whoisonline’ ) ) {
 
            if ( whoisonline.online === false ) {
                //If just loaded, don’t say anything…
                whoisonline.online = data.whoisonline;
            }
            whoisonline.onlinePrev = whoisonline.online ||
 
            for ( var id in whoisonline.onlinePrev ) {
                if ( ! whoisonline.online.hasOwnProperty( id ) ) {
                    jQuery.noticeAdd( { text: whoisonline.onlinePrev[id] + » is now offline» } );
                }
            }
 
            for ( var id in whoisonline.online ) {
                if ( ! whoisonline.onlinePrev.hasOwnProperty( id) ) {
                    jQuery.noticeAdd( { text: whoisonline.online[id] + » is now online» } );
                }
            }
        }
        wp.heartbeat.enqueue( ‘who-is-online’, ‘whoisonline’, false );
    });
});

Этот плагин будет использовать надстройку jQuery Notice от Tim Benniks — легкого плагиноподобного уведомления для jQuery. Просто скачайте его и распакуйте в корень вашего плагина (он должен состоять только из двух файлов: jquery.notice.js и jquery.notice.css )

Теперь, когда добавлен плагин jQuery, последний кусочек головоломки — поставить в очередь необходимые скрипты и стили. Мы хотим, чтобы этот плагин функционировал как на стороне интерфейса, так и на стороне администратора, поэтому мы будем использовать оба admin_enqueue_scripts и wp_enqueue_scripts , но мы хотим загружать скрипт только для зарегистрированных пользователей.

01
02
03
04
05
06
07
08
09
10
11
function whoisonline_load_scripts() {
 
    /* Ony load scripts when you need to — in this case, everywhere if the user is logged in */
    if ( is_user_logged_in() ) {
        wp_enqueue_script( ‘whoisonline-jquery-notice’, plugin_dir_url( __FILE__ ) . ‘jquery.notice.js’, array( ‘jquery’ ) );
        wp_enqueue_style( ‘whoisonline-jquery-notice’, plugin_dir_url( __FILE__ ) . ‘jquery.notice.css’ );
        wp_enqueue_script( ‘whoisonline’, plugin_dir_url( __FILE__ ) . ‘who-is-online.js’, array( ‘heartbeat’, ‘whoisonline-jquery-notice’ ) );
    }
}
add_action( ‘admin_enqueue_scripts’, ‘whoisonline_load_scripts’ );
add_action( ‘wp_enqueue_scripts’, ‘whoisonline_load_scripts’ );

И это готовый плагин.

Вы можете увидеть код в полном объеме в этом GitHub хранилище . Здесь есть много возможностей для улучшения (например, отображение списка пользователей и когда они были активны в последний раз), но, надеюсь, этот относительно простой плагин продемонстрировал, как работает Heartbeat API.