2015-12-30 13 views
25

Zauważyłem, że Facebook zaczął korzystać z powiadomienia HTML5 na pulpicie i myślałem, że zacznę się nim zajmować dla zabawy dla mojego bloga. Mój pomysł jest całkiem prosty: nowy blog wychodzi, cachejob Apache działa co X minut i wywołuje plik, robi trochę magii PHP i wychodzi powiadomienie.Powiadomienie HTML5 z PHP

Sprawdziłem online i znalazłem przykłady przy użyciu node.js and angular, ale nie jestem wygodne przy użyciu któregokolwiek z nich, więc wolę trzymać się z PHP.

Oto mój proces: użytkownik przechodzi do mojego bloga i kliknie przycisk, aby umożliwić powiadomienia. Dla zwięzłości poniższy kod wysyła użytkownikom powiadomienie po kliknięciu przycisku "powiadom". Działa to doskonale i teoretycznie należy je zasubskrybować do przyszłych powiadomień.

if ('Notification' in window) { 

function notifyUser() { 
    var title = 'example title'; 
    var options = { 
     body: 'example body', 
     icon: 'example icon' 
    }; 

    if (Notification.permission === "granted") { 
     var notification = new Notification(title, options); 
    } else if (Notification.permission !== 'denied') { 
     Notification.requestPermission(function (permission) { 
      if (permission === "granted") { 
       var notification = new Notification(title, options); 
      } 
     }); 
    } 

} 

$('#notify').click(function() { 
    notifyUser(); 
    return false; 
}); 

} else { 
    //not happening 
} 

Możesz zobaczyć fiddle powyższych.

Dostęp do użytkownika został przyznany, a teraz powinienem mieć możliwość wysyłania powiadomień kiedy tylko chcę. Niesamowite! Później wpisuję blog i mam identyfikator XYZ. Mój cronjob idzie i wywołuje poniższy skrypt PHP, używając powyższego przykładu node.js jako szablonu.

(w tym przykładzie jestem po prostu wywołanie skryptu ręcznie z mojego telefonu i ogląda mój pulpit. Ponieważ mój pulpit jest „abonament” do tej samej domeny, myślę, że następne będzie/powinno działać.)

$num = $_GET['num']; 

$db = mysql_connect(DB_HOST, DB_USER, DB_PASS); 
if($db) { 
    mysql_select_db('mydb', $db); 
    $select = "SELECT alert FROM blog WHERE id = ".$num." && alert = 0 LIMIT 1"; 
    $results = mysql_query($select) or die(mysql_error()); 
    $output = ''; 
    while($row = mysql_fetch_object($results)) { 

     $output .= "<script> 

     var title = 'new blog!'; 
     var options = { 
      body: 'come read my new blog!', 
      icon: 'same icon as before or maybe a new one!' 
     }; 

     var notification = new Notification(title, options); 

     </script>"; 

     $update = "UPDATE blog SET alert = 1 WHERE id = ".$num." && alert = 0 LIMIT 1"; 
     mysql_query($update) or die(mysql_error()); 

    } 

    echo $output; 

} 

Następnie sprawdzam bazę danych i wpis na blogu "Alert" XYZ jest teraz ustawiony na "1", ale moja przeglądarka komputerowa nigdy nie otrzymała powiadomienia. Ponieważ moja przeglądarka jest subskrybowana tym samym adresem URL, który wypycha powiadomienie, wyobrażam sobie, że dostanę wiadomość.

Albo robię coś nie tak (być może PHP nie jest odpowiednim językiem do tego?), Albo nie rozumiem specyfikacji. Czy ktoś może wskazać mi właściwy kierunek? Chyba coś mi brakuje.

Wielkie dzięki.

Update 1

Według komentarzach, jeśli po prostu wywołaj skrypt z tym w tym:

var title = 'new blog!'; 
var options = { 
    body: 'come read my new blog!', 
    icon: 'same icon as before or maybe a new one!' 
}; 

    var notification = new Notification(title, options); 

To powinno trafić wszystkie urządzenia, które zostały subskrybowane do moich powiadomień. Próbowałem tego na moim telefonie, ale mój pulpit nadal nie otrzymał powiadomienia. Nadal uważam, że coś mi brakuje, ponieważ moje powiadomienia są przyklejone do jednego urządzenia i można je wywoływać tylko na ładowanie strony lub kliknięcie, w przeciwieństwie do Facebooka, które wysyła powiadomienia, nawet jeśli strona nie jest otwarta w przeglądarce.

+0

Należy pobrać adres URL dostarczony przez wielokrotnie z JS, aby przechwytywać zmiany po ich wystąpieniu. możesz pozostawić otwarte połączenie i długą ankietę lub kometę, ale to przesada dla aktualizacji o niskiej częstotliwości, takich jak nowe posty na blogu. – dandavis

+0

Nie rozumiem. Czy po przesłaniu adresu URL i wysłaniu powiadomienia trafi on do wszystkich subskrybowanych użytkowników? Wydaje się, że wysyła tylko to urządzenie, a nie żadne dodatkowe. –

+0

trafi je, gdy następnym razem przeładują stronę lub ajax php. nie ma wbudowanej "subskrypcji" z php, ale jest kilka sposobów na "push". prosty plik RSS jest sposobem lo-fi, a jeśli użytkownik jest subskrybowany, zwykle otrzymuje powiadomienie. – dandavis

Odpowiedz

15

Twoim problemem jest brak AJAX połączyć JavaScript i PHP. Sposób działania skryptu PHP polega na ręcznym uruchomieniu skryptu, dlatego powiadomienie zostanie wyświetlone tylko przez urządzenie trafiające do tego skryptu. Obecnie nic nie przesyła tych informacji na Twoje inne urządzenie.

Aby lepiej wyjaśnić problem, komputer mógł zezwolić na dostęp do powiadomień, ale nie powoduje automatycznego pobierania tych powiadomień. Podany kod będzie musiał użyć AJAX, aby trafić adres URL skryptu, zamiast używać go jako zadania cron.

Po pierwsze, należy uruchomić powtarzające się żądanie w skrypcie PHP, aby sprawdzić, czy nastąpiło jakieś zaktualizowane powiadomienie. Jeśli pojawi się nowe powiadomienie, musisz utworzyć nowy obiekt powiadomienia, używając zwróconej odpowiedzi.

Po drugie, należy zmienić skrypt PHP, aby wyprowadzał łańcuch JSON zamiast skryptu powiadomienia.

JSON wyjście przykład:

{ 
    { 
    title: 'new blog!', 
    options: { 
     body: 'come read my new blog!', 
     icon: 'same icon as before or maybe a new one!' 
    } 
    }, 
    { 
    title: 'another blog item!', 
    options: { 
     body: 'come read my second blog!', 
     icon: 'hooray for icons!' 
    } 
    } 
} 

Twój notifyUsers() powinny title i option jako argumenty zamiast nich hardcoding:

function notifyUser(title, options) { ... } 

jQuery, uzyskać odpowiedź PHP i utworzyć powiadomienie:

function checkNotifications(){ 
    $.get("/path/to/script.php", function(data) { 
    // data is the returned response, let's parse the JSON string 
    json = JSON.parse(data); 

    // check if any items were returned 
    if(!$.isEmptyObject(json)){ 
     // send each item to the notify function 
     for(var i in json){ 
     notifyUser(json[i].title, json[i].options); 
     } 
    } 
    }); 

    setTimeout(checkNotifications, 60000); // call once per minute 
} 

Teraz wystarczy kickstart odpytywanie AJAX, więc dodać do swojej strony internetowej:

$(document).ready(checkNotifications); 

To dość dużo! Po prostu brakowało części, kiedy potrzebny był pulpit do wysyłania powiadomień. Mimo to jednak nie jest testowany i może być konieczne wyszukanie czegoś.

+0

Istnieje interfejs API usługi JS Push służący do konfigurowania modułu Service Worker przeglądarki, ale jest on obsługiwany tylko w przeglądarce Chrome 42.0 (w tym w wersji mobilnej) i Firefox 44.0 (z wyjątkiem urządzeń mobilnych), a obsługa wielu przeglądarek nie jest jeszcze możliwa. Wyeliminowałoby to potrzebę powtarzania żądań AJAX, umożliwiając przeglądarce obsługę pracy. Sprawdź: http://w3c.github.io/push-api/ – Siphon

1

użyć następujących

<button onclick="notifyMe()">Notify me!</button> 

function notifyMe() { 
    // Let's check if the browser supports notifications 
    if (!("Notification" in window)) { 
    alert("This browser does not support desktop notification"); 
    } 

    // Let's check whether notification permissions have already been granted 
    else if (Notification.permission === "granted") { 
    // If it's okay let's create a notification 
    var notification = new Notification("Hi there!"); 
    } 

    // Otherwise, we need to ask the user for permission 
    else if (Notification.permission !== 'denied') { 
    Notification.requestPermission(function (permission) { 
     // If the user accepts, let's create a notification 
     if (permission === "granted") { 
     var notification = new Notification("Hi there!"); 
     } 
    }); 
    } 

    // At last, if the user has denied notifications, and you 
    // want to be respectful there is no need to bother them any more. 
}