Como utilizar Os Hubs de Notificação do PHP

Pode aceder a todas as funcionalidades dos Notification Hubs a partir de um back-end Java/PHP/Ruby através da interface REST do Hub de Notificação, conforme descrito no tópico MSDN ApIs REST dos Hubs de Notificação.

Neste tópico, mostramos como:

Interface de cliente

A interface de cliente principal pode fornecer os mesmos métodos que estão disponíveis no SDK dos Hubs de Notificação .NET, o que lhe permite traduzir diretamente todos os tutoriais e exemplos atualmente disponíveis neste site e contribuidos pela comunidade na Internet.

Pode encontrar todo o código disponível no exemplo de wrapper REST do PHP.

Por exemplo, para criar um cliente:

$hub = new NotificationHub("connection string", "hubname");

Para enviar uma notificação nativa do iOS:

$notification = new Notification("apple", '{"aps":{"alert": "Hello!"}}');
$hub->sendNotification($notification, null);

Implementação

Se ainda não o fez, siga o [Tutorial de introdução] até à última secção onde tem de implementar o back-end. Além disso, se quiser, pode utilizar o código do exemplo de wrapper REST do PHP e aceder diretamente à secção Concluir o tutorial .

Todos os detalhes para implementar um wrapper REST completo podem ser encontrados no MSDN. Nesta secção, descrevemos a implementação do PHP dos principais passos necessários para aceder aos pontos finais REST dos Hubs de Notificação:

  1. Analisar a cadeia de ligação
  2. Gerar o token de autorização
  3. Executar a chamada HTTP

Analisar a cadeia de ligação

Eis a classe principal que implementa o cliente, cujo construtor analisa a cadeia de ligação:

class NotificationHub {
    const API_VERSION = "?api-version=2013-10";

    private $endpoint;
    private $hubPath;
    private $sasKeyName;
    private $sasKeyValue;

    function __construct($connectionString, $hubPath) {
        $this->hubPath = $hubPath;

        $this->parseConnectionString($connectionString);
    }

    private function parseConnectionString($connectionString) {
        $parts = explode(";", $connectionString);
        if (sizeof($parts) != 3) {
            throw new Exception("Error parsing connection string: " . $connectionString);
        }

        foreach ($parts as $part) {
            if (strpos($part, "Endpoint") === 0) {
                $this->endpoint = "https" . substr($part, 11);
            } else if (strpos($part, "SharedAccessKeyName") === 0) {
                $this->sasKeyName = substr($part, 20);
            } else if (strpos($part, "SharedAccessKey") === 0) {
                $this->sasKeyValue = substr($part, 16);
            }
        }
    }
}

Criar um token de segurança

Veja a documentação do Azure para obter informações sobre como Criar um Token de Segurança de SAS.

Adicione o generateSasToken método à NotificationHub classe para criar o token com base no URI do pedido atual e nas credenciais extraídas da cadeia de ligação.

private function generateSasToken($uri) {
    $targetUri = strtolower(rawurlencode(strtolower($uri)));

    $expires = time();
    $expiresInMins = 60;
    $expires = $expires + $expiresInMins * 60;
    $toSign = $targetUri . "\n" . $expires;

    $signature = rawurlencode(base64_encode(hash_hmac('sha256', $toSign, $this->sasKeyValue, TRUE)));

    $token = "SharedAccessSignature sr=" . $targetUri . "&sig="
                . $signature . "&se=" . $expires . "&skn=" . $this->sasKeyName;

    return $token;
}

Enviar uma notificação

Primeiro, vamos definir uma classe que representa uma notificação.

class Notification {
    public $format;
    public $payload;

    # array with keynames for headers
    # Note: Some headers are mandatory: Windows: X-WNS-Type, WindowsPhone: X-NotificationType
    # Note: For Apple you can set Expiry with header: ServiceBusNotification-ApnsExpiry in W3C DTF, YYYY-MM-DDThh:mmTZD (for example, 1997-07-16T19:20+01:00).
    public $headers;

    function __construct($format, $payload) {
        if (!in_array($format, ["template", "apple", "windows", "fcm", "windowsphone"])) {
            throw new Exception('Invalid format: ' . $format);
        }

        $this->format = $format;
        $this->payload = $payload;
    }
}

Esta classe é um contentor para um corpo de notificação nativo ou um conjunto de propriedades no caso de uma notificação de modelo e um conjunto de cabeçalhos, que contém formato (plataforma ou modelo nativo) e propriedades específicas da plataforma (como a propriedade de expiração da Apple e cabeçalhos WNS).

Veja a documentação das APIs REST dos Hubs de Notificação e os formatos das plataformas de notificação específicas para obter todas as opções disponíveis.

Munidos desta classe, podemos agora escrever os métodos de notificação de envio dentro da NotificationHub classe :

public function sendNotification($notification, $tagsOrTagExpression="") {
    if (is_array($tagsOrTagExpression)) {
        $tagExpression = implode(" || ", $tagsOrTagExpression);
    } else {
        $tagExpression = $tagsOrTagExpression;
    }

    # build uri
    $uri = $this->endpoint . $this->hubPath . "/messages" . NotificationHub::API_VERSION;
    $ch = curl_init($uri);

    if (in_array($notification->format, ["template", "apple", "fcm"])) {
        $contentType = "application/json";
    } else {
        $contentType = "application/xml";
    }

    $token = $this->generateSasToken($uri);

    $headers = [
        'Authorization: '.$token,
        'Content-Type: '.$contentType,
        'ServiceBusNotification-Format: '.$notification->format
    ];

    if ("" !== $tagExpression) {
        $headers[] = 'ServiceBusNotification-Tags: '.$tagExpression;
    }

    # add headers for other platforms
    if (is_array($notification->headers)) {
        $headers = array_merge($headers, $notification->headers);
    }

    curl_setopt_array($ch, array(
        CURLOPT_POST => TRUE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => $notification->payload
    ));

    // Send the request
    $response = curl_exec($ch);

    // Check for errors
    if($response === FALSE){
        throw new Exception(curl_error($ch));
    }

    $info = curl_getinfo($ch);

    if ($info['http_code'] <> 201) {
        throw new Exception('Error sending notification: '. $info['http_code'] . ' msg: ' . $response);
    }
} 

Os métodos acima enviam um pedido HTTP POST para o /messages ponto final do hub de notificação, com o corpo e os cabeçalhos corretos para enviar a notificação.

Concluir o tutorial

Agora, pode concluir o tutorial Introdução ao enviar a notificação a partir de um back-end PHP.

Inicialize o cliente dos Notification Hubs (substitua a cadeia de ligação e o nome do hub conforme indicado no [Tutorial de introdução]):

$hub = new NotificationHub("connection string", "hubname");

Em seguida, adicione o código de envio consoante a sua plataforma móvel de destino.

Loja Windows e Windows Phone 8.1 (não Silverlight)

$toast = '<toast><visual><binding template="ToastText01"><text id="1">Hello from PHP!</text></binding></visual></toast>';
$notification = new Notification("windows", $toast);
$notification->headers[] = 'X-WNS-Type: wns/toast';
$hub->sendNotification($notification, null);

iOS

$alert = '{"aps":{"alert":"Hello from PHP!"}}';
$notification = new Notification("apple", $alert);
$hub->sendNotification($notification, null);

Android

$message = '{"data":{"msg":"Hello from PHP!"}}';
$notification = new Notification("fcm", $message);
$hub->sendNotification($notification, null);

Windows Phone 8.0 e 8.1 Silverlight

$toast = '<?xml version="1.0" encoding="utf-8"?>' .
            '<wp:Notification xmlns:wp="WPNotification">' .
               '<wp:Toast>' .
                    '<wp:Text1>Hello from PHP!</wp:Text1>' .
               '</wp:Toast> ' .
            '</wp:Notification>';
$notification = new Notification("windowsphone", $toast);
$notification->headers[] = 'X-WindowsPhone-Target : toast';
$notification->headers[] = 'X-NotificationClass : 2';
$hub->sendNotification($notification, null);

Fogo Kindle

$message = '{"data":{"msg":"Hello from PHP!"}}';
$notification = new Notification("adm", $message);
$hub->sendNotification($notification, null);

A execução do código PHP deverá produzir agora uma notificação apresentada no seu dispositivo de destino.

Passos Seguintes

Neste tópico, mostrámos como criar um cliente REST PHP simples para Hubs de Notificação. A partir daqui, pode:

  • Transfira o exemplo completo do wrapper REST PHP, que contém todo o código acima.
  • Continue a saber mais sobre a funcionalidade de identificação dos Hubs de Notificação no [tutorial de Notícias de Última Hora]
  • Saiba mais sobre enviar notificações push para utilizadores individuais no [tutorial Notificar Utilizadores]

Para obter mais informações, veja também o Centro de Programadores PHP.

Enviar notificações push para aplicações iOS com os Hubs de Notificação do Azure