1 of 71

Heartbeat API

Jaroslav Polakovič

WordPress Engineer, XWP.co

WordCamp 2015, Praha

2 of 71

Web s Heartbeat API

3 of 71

Web bez Heartbeat API

4 of 71

CO TO TEDA DĚLÁ?

5 of 71

Heartbeat

  • Čekání: 60 sekund (ačkoli…)

6 of 71

Heartbeat

  • Čekání: 60 sekund
  • AJAX požadavek na server

7 of 71

Heartbeat

  • Čekání: 60 sekund
  • AJAX požadavek na server
  • Odezva serveru (tick)

8 of 71

Heartbeat

Čekání: 60 sekund

AJAX požadavek na server

Odezva serveru (tick)

… á znovu!

9 of 71

Heartbeat

Čekání: 60 sekund

AJAX požadavek na server

Odezva serveru (tick)

… á znovu!

Pff, to už dávno umím!

10 of 71

Heartbeat

Čekání: 60 sekund

AJAX požadavek na server

Odezva serveru (tick)

… á znovu!

A na tomhle nic není!

11 of 71

Heartbeat ver 0.001alpha

setInterval( function() {� jQuery.get( ajaxURL, function( data ) {� console.log( data );� }�}, 60000 );��// Hotovo, ne?

12 of 71

13 of 71

Ale co když… ?

Co když chci na server posílat data z různých míst v mém JavaScriptovém kódu?

14 of 71

Ale co když… ?

Co když chci na server posílat data z různých míst v mém JavaScriptovém kódu?

Prostě to zapouzdřím!

A použiju metodu POST.

15 of 71

Ale co když… ?

Co když chci na serveru mít možnost měnit data, která se odesílají v odpovědi?

16 of 71

Ale co když… ?

Co když chci na serveru mít možnost měnit data, která se odesílají v odpovědi?

Prostě použiju filtry!

add_filter()

apply_filters()

17 of 71

Ale co když… ?

Co když je server pomalý a ještě nedoručil odpověď na předchozí požadavek?

18 of 71

Ale co když… ?

Co když je server pomalý a ještě nedoručil odpověď na předchozí požadavek?

Prostě počkám!

19 of 71

Ale co když… ?

Co když server spadne nebo vrátí nějakou jinou divnou chybu?

20 of 71

Ale co když… ?

Co když server spadne nebo vrátí nějakou jinou divnou chybu?

Prostě to ošetřím!

21 of 71

Ale co když… ?

Co když chci posílat míň požadavků na server, když uživatel stránku zrovna nepoužívá?

22 of 71

Ale co když… ?

Co když chci posílat míň požadavků na server, když uživatel stránku zrovna nepoužívá?

Prostě použiju Page Visibility API!

23 of 71

Ale co když… ?

Co když chci posílat míň požadavků na server, když uživatel stránku zrovna nepoužívá?

Prostě použiju Page Visibility API!

(a v hloupých prohlížečích budu hlídat události keyUp a mouseOver)

24 of 71

Ale co když… ?

Co když chci posílat míň požadavků na server, když uživatel stránku zrovna nepoužívá?

Prostě použiju Page Visibility API!

(a v hloupých prohlížečích budu hlídat události keyUp a mouseOver)

(a vlastně teda ještě touchEnd)

25 of 71

Ale co když… ?

Co když chci posílat míň požadavků na server, když uživatel stránku zrovna nepoužívá?

Prostě použiju Page Visibility API!

(a v hloupých prohlížečích budu hlídat události keyUp a mouseOver)

(a vlastně teda ještě touchEnd)

(jo, a ještě si musím dát pozor na framy)

26 of 71

Ugh...

27 of 71

Heartbeat API

pořád Jaroslav Polakovič

pořád WordPress Engineer, XWP.co

pořád WordCamp 2015, Praha

28 of 71

Heartbeat API

  • Slouží k pravidelné výměně dat mezi klientem a serverem bez obnovení stránky.
  • Umožňuje jednoduchou správu odesílaných a přijímaných dat.
  • A to jak na straně klienta, tak na serveru.
  • WordPress jej využívá interně v administraci.

29 of 71

30 of 71

31 of 71

32 of 71

Klient -> Server

data[wp-refresh-post-lock][post_id]: 23

data[wp-refresh-post-lock][lock]: 1425030300:2

interval: 15

_nonce: 5df8699121

action: heartbeat

screen_id: post

has_focus: false

Server -> Klient

{

"wp-refresh-post-lock": {

"new_lock": "1425030315:2"

},

"wp-auth-check": true,

"server_time": 1425030315

}

33 of 71

NÁKUPNÍ SEZNAMY

  • JS: SEZNAM METOD OBJEKTU WP.HEARTBEAT
  • PHP: FILTRY A AKCE

Psst, tajný tip…

/wp-includes/js/heartbeat.js

/wp-admin/includes/ajax-actions.php

+

https://developer.wordpress.org/reference/

34 of 71

NÁKUPNÍ SEZNAMY

  • JS: SEZNAM METOD OBJEKTU WP.HEARTBEAT
  • PHP: FILTRY A AKCE

Psst, tajný tip…

/wp-includes/js/heartbeat.js

/wp-admin/includes/ajax-actions.php

+

https://developer.wordpress.org/reference/

35 of 71

Heartbeat API - PHP

Jak vlastně Heartbeat do stránky dostanu?

// Buď...�wp_enqueue_script('heartbeat');��// Anebo�wp_enqueue_script(� 'muj-skript',� get_template_directory_uri() . '/js/muj_skript.js',� array('heartbeat')�);

36 of 71

Heartbeat API - PHP

V reálu je to jenom o málo složitější:

// Kdekoli ve functions.phpfunction load_heartbeat() {� if ( is_single() ) {� wp_enqueue_script( 'heartbeat' );� } �}�add_action( 'wp_enqueue_scripts', 'load_heartbeat' );

37 of 71

Heartbeat API - PHP

Heartbeat API exponuje 3 (sic!) filtry a 1 (sic!) akci:

// filtryheartbeat_settings

heartbeat_received, heartbeat_nopriv_received�heartbeat_send, heartbeat_nopriv_send��// akce�heartbeat_tick, heartbeat_nopriv_tick

38 of 71

Heartbeat API - PHP

Změna výchozího nastavení pomocí filtru:

// Kdekoli ve functions.phpfunction my_heartbeat_settings( $settings ) {� $settings['interval'] = 15;� if ( is_front_page() ) {� $settings['screenId'] = 'homepage';� }� return $settings;�}�add_filter('heartbeat_settings', 'my_heartbeat_settings');

39 of 71

Heartbeat API - PHP

Odpověď na podnět z klienta:

// Kdekoli ve functions.phpfunction my_response( $response, $data, $screen_id ) {� if ( $screen_id === 'homepage' && isset( $data['pozdrav'] ) ) {� $response['ahoj'] = 'svete';� }� return $response;�}�add_filter( 'heartbeat_received', 'my_response', 10, 3 );

add_filter( 'heartbeat_nopriv_received', 'my_response', 10, 3 );

40 of 71

Heartbeat API - JavaScript

Veřejné metody objektu wp.heartbeat:

function connectNow() {};�function dequeue( handle ) {};�function disableSuspend() {};�function enqueue( handle, data, noOverwrite ) {};�function getQueuedItem( handle ) {};�function hasConnectionError() {};�function hasFocus() {};�function interval( speed, ticks ) {};�function isQueued( handle ) {};

41 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue(� 'wordcamp-2015',� {� 'zprava': 'Už se těším na oběd.',� },� false�);

42 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue(� 'wordcamp-2015',� {� 'zprava': 'Už se těším na oběd.',� },� false�);

43 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue('wordcamp-2015',� {� 'zprava': 'Už se těším na oběd.',� },� false);

44 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue(� 'wordcamp-2015',� {� 'zprava': 'Už se těším na oběd.',� },� false�);

45 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue(� 'wordcamp-2015',� {'zprava': 'Už se těším na oběd.',� },� false�);

46 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue(� 'wordcamp-2015',� {� 'zprava': 'Už se těším na oběd.',� },� false�);

47 of 71

Heartbeat API - JavaScript

Události, které wp.heartbeat emituje:

heartbeat-send [heartbeatData]

heartbeat-tick [response, textStatus, jqXHR]

heartbeat-error [jqXHR, textStatus, error]

heartbeat-connection-lost [error, status]

heartbeat-connection-restored

heartbeat-nonces-expired

48 of 71

Heartbeat API - JavaScript

wp.heartbeat.enqueue('pro_server', 'ABC'); ��jQuery(document).on('heartbeat-send', function(e, data) {� data['pro_server'] = 'XYZ';�});

49 of 71

PŘÍKLAD

50 of 71

PŘÍKLAD

s (velmi podstatnou) chybou…

51 of 71

Počet nových příspěvků

Mám web s vtipnými obrázky a na hlavní stránce chci uživatelům ukázat, kolik nových obrázků přibylo od chvíle, kdy naposledy obnovili stránku.

52 of 71

functions.php 1/2

function load_newposts_script() {� if ( is_front_page() ) {� wp_enqueue_script(� 'newposts',� get_template_directory_uri() . '/js/newposts.js',� array( 'heartbeat' )� );� }�}�add_action( 'wp_enqueue_scripts', 'load_newposts_script' );

53 of 71

newposts.js 1/2

var timestamp = Math.floor( Date.now() / 1000 );��jQuery(document).on('heartbeat-send', function(e, data) {� data['newposts'] = { newposts_from : timestamp };�});

54 of 71

functions.php 2/2

function np_handler( $response, $data, $screen_id ) {� if ( isset( $data['newposts']['newposts_from'] ) ) {� // WP_Query -> $new_posts_count, $last_post_timestampif ( $new_posts_count > 0 ) {� $response['newposts'] = array(� 'count' => $new_posts_count,� 'timestamp' => $last_post_timestamp,� );� }� }� return $response;�}�add_filter( 'heartbeat_received', 'np_handler', 10, 3 );�add_filter( 'heartbeat_nopriv_received', 'np_handler', 10, 3 );

55 of 71

newposts.js 2/2

var timestamp = Math.floor( Date.now() / 1000 );��jQuery(document).on('heartbeat-send', function(e, data) {� data['newposts'] = { newposts_from : timestamp };�});

�jQuery(document).on('heartbeat-tick', function(e, response) {� if ( response.newposts ) {� newPostsCount = response.newposts.count;� timestamp = response.newposts.timestamp;�� // Nějak zobrazíme newPostsCount� }�});

56 of 71

KDE BYLA CHYBA?

57 of 71

58 of 71

59 of 71

Výkon je všechno

  • Každý tep znamená, že se na serveru musí spustit nemalá část WordPressu.
  • Každý request si může vzít v lepším případě pár desítek ms procesorového času…
  • … ale můžou to být i sekundy!
  • Co se stane, pokud na web přijde zároveň pár stovek návštěvníků?

60 of 71

61 of 71

62 of 71

HEARTBEAT

NA

FRONTENDU?

63 of 71

64 of 71

Opatrně

  • Heartbeat není kladivo, nepoužívejte ho tak.

65 of 71

Opatrně

  • Heartbeat není kladivo, nepoužívejte ho tak.
  • Když už potřebujete kladivo, použijte ho jen v nezbytné míře, viz třeba BuddyPress.
    • I ten to dělá blbě, ale jenom proto, že potřebuje být podporován na mnoha různých platformách.

66 of 71

Opatrně

  • Heartbeat není kladivo, nepoužívejte ho tak.
  • Když už potřebujete kladivo, použijte ho jen v nezbytné míře, viz třeba BuddyPress.
    • I ten to dělá blbě, ale jenom proto, že potřebuje být podporován na mnoha různých platformách.
  • Nešlo by to cachovat?

67 of 71

Opatrně

  • Heartbeat není kladivo, nepoužívejte ho tak.
  • Když už potřebujete kladivo, použijte ho jen v nezbytné míře, viz třeba BuddyPress.
    • I ten to dělá blbě, ale jenom proto, že potřebuje být podporován na mnoha různých platformách.
  • Nešlo by to cachovat?
  • Nešlo by vytvořit vlastní endpoint?
    • Bez WordPressu?
    • SHORTINIT?

68 of 71

RYCHLÉ OPÁČKO

69 of 71

Rychlé opáčko

  • Heartbeat API umožňuje bez obnovení stránky posílat data na server a přijímat odpovědi.
  • Heartbeat se načítá jenom v administraci.
  • Klient: wp.heartbeat a jeho metody a události.
  • Server: Filtry a akce.
  • Dvakrát měřit, jednou řezat.
  • Pozor na výkon!

70 of 71

TOŤ VŠE

(pun intended)

Chcete se na něco zeptat?

71 of 71

DÍKY ZA

POZORNOST!

Slajdy na adrese

j.mp/heartbeat-api