All Projects → pusher → Pusher Http Php

pusher / Pusher Http Php

PHP library for interacting with the Pusher Channels HTTP API

Projects that are alternatives of or similar to Pusher Http Php

Pusher Http Laravel
[DEPRECATED] A Pusher Channels bridge for Laravel
Stars: ✭ 410 (-63.91%)
Mutual labels:  pusher, composer
Packagist Mirror
Alibaba Cloud Packagist Mirror
Stars: ✭ 63 (-94.45%)
Mutual labels:  composer
Realtime Mongodb Pusher
Sample app that shows how to use MongoDB change streams and Pusher in a Node.js/React app
Stars: ✭ 44 (-96.13%)
Mutual labels:  pusher
Spinupwp Composer Site
A WordPress site setup using Composer that is primed and ready to be hosted using SpinupWP.
Stars: ✭ 58 (-94.89%)
Mutual labels:  composer
Composer Patches
Simple patches plugin for Composer
Stars: ✭ 1,033 (-9.07%)
Mutual labels:  composer
Php
PHP 文章集锦,浮点数搞定度运算、签名验证、单点登录、安全防御、缓存技术、RPC、Composer ...
Stars: ✭ 61 (-94.63%)
Mutual labels:  composer
Cloudreve
🌩支持多家云存储的云盘系统 (Self-deployed file management and sharing system, supports multiple storage providers)
Stars: ✭ 12,318 (+984.33%)
Mutual labels:  composer
Formula Parser
Parsing and evaluating mathematical formulas given as strings.
Stars: ✭ 62 (-94.54%)
Mutual labels:  composer
Pkgmirror
Packages Mirroring
Stars: ✭ 62 (-94.54%)
Mutual labels:  composer
Php frameworks analysis
php框架源码分析
Stars: ✭ 57 (-94.98%)
Mutual labels:  composer
Airflow Toolkit
Any Airflow project day 1, you can spin up a local desktop Kubernetes Airflow environment AND one in Google Cloud Composer with tested data pipelines(DAGs) 🖥 >> [ 🚀, 🚢 ]
Stars: ✭ 51 (-95.51%)
Mutual labels:  composer
Larrock Core
Core components for LarrockCMS
Stars: ✭ 46 (-95.95%)
Mutual labels:  composer
Mailchimp Api 3.0 Php
A feature rich object-oriented PHP library for interacting with MailChimp's API v3 💌🐵
Stars: ✭ 61 (-94.63%)
Mutual labels:  composer
Datagrid
Datagrid for Laravel v5
Stars: ✭ 44 (-96.13%)
Mutual labels:  composer
Deb Dev Machine
Quickly install common Developer tools, IDE's & Services on Debian 9
Stars: ✭ 63 (-94.45%)
Mutual labels:  composer
Composer Notifier
💬 Display desktop notification after Composer install / update
Stars: ✭ 42 (-96.3%)
Mutual labels:  composer
Beaver
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.
Stars: ✭ 1,056 (-7.04%)
Mutual labels:  pusher
Codice Fiscale
A PHP library to calculate and check the italian tax code (codice fiscale).
Stars: ✭ 57 (-94.98%)
Mutual labels:  composer
Conductor
Conductor makes it easy to mange multiple composer packages within a single source repository
Stars: ✭ 64 (-94.37%)
Mutual labels:  composer
Scriptsdev
Scripts-dev directive for composer
Stars: ✭ 63 (-94.45%)
Mutual labels:  composer

Pusher Channels HTTP PHP Library

Tests Packagist Version Packagist License Packagist Downloads

PHP library for interacting with the Pusher Channels HTTP API.

Register at https://pusher.com and use the application credentials within your app as shown below.

Installation

You can get the Pusher Channels PHP library via a composer package called pusher-php-server. See https://packagist.org/packages/pusher/pusher-php-server

$ composer require pusher/pusher-php-server

Or add to composer.json:

"require": {
	"pusher/pusher-php-server": "^6.0"
}

and then run composer update.

Supported platforms

  • PHP - supports PHP versions 7.2, 7.3, 7.4 and 8.0.
  • Laravel - version 8.29 and above has built-in support for Pusher Channels as a Broadcasting backend.
  • Other PHP frameworks - supported provided you are using a supported version of PHP.

Pusher Channels constructor

Use the credentials from your Pusher Channels application to create a new Pusher\Pusher instance.

$app_id = 'YOUR_APP_ID';
$app_key = 'YOUR_APP_KEY';
$app_secret = 'YOUR_APP_SECRET';
$app_cluster = 'YOUR_APP_CLUSTER';

$pusher = new Pusher\Pusher( $app_key, $app_secret, $app_id, array('cluster' => $app_cluster) );

The fourth parameter is an $options array. The additional options are:

  • scheme - e.g. http or https
  • host - the host e.g. api.pusherapp.com. No trailing forward slash
  • port - the http port
  • path - a prefix to append to all request paths. This is only useful if you are running the library against an endpoint you control yourself (e.g. a proxy that routes based on the path prefix).
  • timeout - the HTTP timeout
  • useTLS - quick option to use scheme of https and port 443.
  • cluster - specify the cluster where the application is running from.
  • encryption_master_key - a 32 char long key. This key, along with the channel name, are used to derive per-channel encryption keys. Per-channel keys are used encrypt event data on encrypted channels.

For example, by default calls will be made over HTTPS. To use plain HTTP you can set useTLS to false:

$options = [
  'cluster' => $app_cluster,
  'useTLS' => false
];
$pusher = new Pusher\Pusher( $app_key, $app_secret, $app_id, $options );

Logging configuration

The recommended approach of logging is to use a PSR-3 compliant logger implementing Psr\Log\LoggerInterface. The Pusher object implements Psr\Log\LoggerAwareInterface, meaning you call setLogger(LoggerInterface $logger) to set the logger instance.

// where $logger implements `LoggerInterface`

$pusher->setLogger($logger);

Custom Guzzle client

This library uses Guzzle internally to make HTTP calls. You can pass your own Guzzle instance to the Pusher constructor:

$custom_client = new GuzzleHttp\Client();

$pusher = new Pusher\Pusher(
	$app_key,
	$app_secret,
	$app_id,
	array(),
	$custom_client
	)
);

This allows you to pass in your own middleware, see the tests for an example.

Publishing/Triggering events

To trigger an event on one or more channels use the trigger function.

A single channel

$pusher->trigger( 'my-channel', 'my_event', 'hello world' );

Multiple channels

$pusher->trigger( [ 'channel-1', 'channel-2' ], 'my_event', 'hello world' );

Batches

It's also possible to send multiple events with a single API call (max 10 events per call on multi-tenant clusters):

$batch = array();
$batch[] = array('channel' => 'my-channel', 'name' => 'my_event', 'data' => array('hello' => 'world'));
$batch[] = array('channel' => 'my-channel', 'name' => 'my_event', 'data' => array('myname' => 'bob'));
$pusher->triggerBatch($batch);

Arrays

Objects are automatically converted to JSON format:

$array['name'] = 'joe';
$array['message_count'] = 23;

$pusher->trigger('my_channel', 'my_event', $array);

The output of this will be:

"{'name': 'joe', 'message_count': 23}"

Socket id

In order to avoid duplicates you can optionally specify the sender's socket id while triggering an event:

$pusher->trigger('my-channel', 'event', 'data', array('socket_id' => $socket_id));
$batch = array();
$batch[] = array('channel' => 'my-channel', 'name' => 'my_event', 'data' => array('hello' => 'world'), array('socket_id' => $socket_id));
$batch[] = array('channel' => 'my-channel', 'name' => 'my_event', 'data' => array('myname' => 'bob'), array('socket_id' => $socket_id);
$pusher->triggerBatch($batch);

Fetch channel info on publish [EXPERIMENTAL]

It is possible to request for attributes about the channels that were published to with the info param:

$result = $pusher->trigger('my-channel', 'my_event', 'hello world', array('info' => 'subscription_count'));
$subscription_count = $result->channels['my-channel']->subscription_count;
$batch = array();
$batch[] = array('channel' => 'my-channel', 'name' => 'my_event', 'data' => array('hello' => 'world'), 'info' => 'subscription_count');
$batch[] = array('channel' => 'presence-my-channel', 'name' => 'my_event', 'data' => array('myname' => 'bob'), 'info' => 'user_count,subscription_count');
$result = $pusher->triggerBatch($batch);

foreach ($result->batch as $i => $attributes) {
  echo "channel: {$batch[$i]['channel']}, name: {$batch[$i]['name']}";
  if (isset($attributes->subscription_count)) {
	echo ", subscription_count: {$attributes->subscription_count}";
  }
  if (isset($attributes->user_count)) {
	echo ", user_count: {$attributes->user_count}";
  }
  echo PHP_EOL;
}

JSON format

If your data is already encoded in JSON format, you can avoid a second encoding step by setting the sixth argument true, like so:

$pusher->trigger('my-channel', 'event', 'data', array(), true)

Authenticating Private channels

To authorise your users to access private channels on Pusher, you can use the socket_auth function:

$pusher->socket_auth('private-my-channel','socket_id');

Authenticating Presence channels

Using presence channels is similar to private channels, but you can specify extra data to identify that particular user:

$pusher->presence_auth('presence-my-channel','socket_id', 'user_id', 'user_info');

Webhooks

This library provides a way of verifying that webhooks you receive from Pusher are actually genuine webhooks from Pusher. It also provides a structure for storing them. A helper method called webhook enables this. Pass in the headers and body of the request, and it'll return a Webhook object with your verified events. If the library was unable to validate the signature, an exception is thrown instead.

$webhook = $pusher->webhook($request_headers, $request_body);
$number_of_events = count($webhook->get_events());
$time_recieved = $webhook->get_time_ms();

End to end encryption

This library supports end to end encryption of your private channels. This means that only you and your connected clients will be able to read your messages. Pusher cannot decrypt them. You can enable this feature by following these steps:

  1. You should first set up Private channels. This involves creating an authentication endpoint on your server.

  2. Next, generate your 32 byte master encryption key, base64 encode it and store it securely. This is secret and you should never share this with anyone. Not even Pusher.

    To generate an appropriate key from a good random source, you can use the openssl command:

    openssl rand -base64 32
    
  3. Specify your master encryption key when creating your Pusher client:

    $pusher = new Pusher\Pusher(
        $app_key,
        $app_secret,
        $app_id,
        array(
     	   'cluster' => $app_cluster,
     	   'encryption_master_key_base64' => "<your base64 encoded master key>"
        )
    );
    
  4. Channels where you wish to use end to end encryption should be prefixed with private-encrypted-.

  5. Subscribe to these channels in your client, and you're done! You can verify it is working by checking out the debug console on the https://dashboard.pusher.com/ and seeing the scrambled ciphertext.

Important note: This will not encrypt messages on channels that are not prefixed by private-encrypted-.

Limitation: you cannot trigger a single event on multiple channels in a call to trigger, e.g.

$data['name'] = 'joe';
$data['message_count'] = 23;

$pusher->trigger(array('channel-1', 'private-encrypted-channel-2'), 'test_event', $data);

Rationale: the methods in this library map directly to individual Channels HTTP API requests. If we allowed triggering a single event on multiple channels (some encrypted, some unencrypted), then it would require two API requests: one where the event is encrypted to the encrypted channels, and one where the event is unencrypted for unencrypted channels.

Presence example

First set this variable in your JS app:

Pusher.channel_auth_endpoint = '/presence_auth.php';

Next, create the following in presence_auth.php:

<?php
if (isset($_SESSION['user_id'])) {
  $stmt = $pdo->prepare("SELECT * FROM `users` WHERE id = :id");
  $stmt->bindValue(':id', $_SESSION['user_id'], PDO::PARAM_INT);
  $stmt->execute();
  $user = $stmt->fetch();
} else {
  die('aaargh, no-one is logged in');
}

header('Content-Type: application/json');

$pusher = new Pusher\Pusher($key, $secret, $app_id);
$presence_data = array('name' => $user['name']);

echo $pusher->presence_auth($_POST['channel_name'], $_POST['socket_id'], $user['id'], $presence_data);

Note: this assumes that you store your users in a table called users and that those users have a name column. It also assumes that you have a login mechanism that stores the user_id of the logged in user in the session.

Application State Queries

Get information about a channel

$pusher->get_channel_info( $name );

It's also possible to get information about a channel from the Channels HTTP API.

$info = $pusher->get_channel_info('channel-name');
$channel_occupied = $info->occupied;

For presence channels you can also query the number of distinct users currently subscribed to this channel (a single user may be subscribed many times, but will only count as one):

$info = $pusher->get_channel_info('presence-channel-name', array('info' => 'user_count'));
$user_count = $info->user_count;

If you have enabled the ability to query the subscription_count (the number of connections currently subscribed to this channel) then you can query this value as follows:

$info = $pusher->get_channel_info('presence-channel-name', array('info' => 'subscription_count'));
$subscription_count = $info->subscription_count;

Get a list of application channels

$pusher->get_channels()

It's also possible to get a list of channels for an application from the Channels HTTP API.

$result = $pusher->get_channels();
$channel_count = count($result->channels); // $channels is an Array

Get a filtered list of application channels

$pusher->get_channels( array( 'filter_by_prefix' => 'some_filter' ) )

It's also possible to get a list of channels based on their name prefix. To do this you need to supply an $options parameter to the call. In the following example the call will return a list of all channels with a presence- prefix. This is idea for fetching a list of all presence channels.

$results = $pusher->get_channels( array( 'filter_by_prefix' => 'presence-') );
$channel_count = count($result->channels); // $channels is an Array

This can also be achieved using the generic pusher->get function:

$pusher->get( '/channels', array( 'filter_by_prefix' => 'presence-' ) );

Get a list of application channels with subscription counts

The HTTP API returning the channel list does not support returning the subscription count along with each channel. Instead, you can fetch this data by iterating over each channel and making another request. But be warned: this approach consumes (number of channels + 1) messages!

<?php
$subscription_counts = array();
foreach ($pusher->get_channels()->channels as $channel => $v) {
  $subscription_counts[$channel] =
	$pusher->get_channel_info(
	  $channel, array('info' => 'subscription_count'))->subscription_count;
}
var_dump($subscription_counts);

Get user information from a presence channel

$results = $pusher->get_users_info( 'presence-channel-name' );
$users_count = count($results->users); // $users is an Array

This can also be achieved using the generic pusher->get function:

$response = $pusher->get( '/channels/presence-channel-name/users' )

The $response is in the format:

Array (
	[body] => {"users":[{"id":"a_user_id"}]}
	[status] => 200
	[result] => Array (
		[users] => Array (
			[0] => Array (
				[id] => a_user_id
			),
			/* Additional users */
		)
	)
)

Generic get function

$pusher->get( $path, $params );

Used to make GET queries against the Channels HTTP API. Handles authentication.

Response is an associative array with a result index. The contents of this index is dependent on the HTTP method that was called. However, a status property to allow the HTTP status code is always present and a result property will be set if the status code indicates a successful call to the API.

$response = $pusher->get( '/channels' );
$http_status_code = $response[ 'status' ];
$result = $response[ 'result' ];

Running the tests

Requires phpunit.

  • Run composer install
  • Go to the tests directory
  • Rename config.example.php and replace the values with valid Channels credentials or create environment variables.
  • Some tests require a client to be connected to the app you defined in the config; you can do this by opening https://dashboard.pusher.com/apps/<YOUR_TEST_APP_ID>/getting_started in the browser
  • From the root directory of the project, execute composer exec phpunit to run all the tests.

License

Copyright 2014, Pusher. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php

Copyright 2010, Squeeks. Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].