Git Product home page Git Product logo

pusher-http-php's Introduction

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": "^7.2"
}

then run composer update.

Supported platforms

  • PHP - supports PHP versions 7.3, 7.4, 8.0, and 8.1.
  • 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, ['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_base64 - 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,
    [],
    $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 = [];
$batch[] = ['channel' => 'my-channel', 'name' => 'my_event', 'data' => ['hello' => 'world']];
$batch[] = ['channel' => 'my-channel', 'name' => 'my_event', 'data' => ['myname' => 'bob']];
$pusher->triggerBatch($batch);

Asynchronous interface

Both trigger and triggerBatch have asynchronous counterparts in triggerAsync and triggerBatchAsync. These functions return Guzzle promises which can be chained with ->then:

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

$promise->then(function($result) {
  // do something with $result
  return $result;
});

$final_result = $promise->wait();

Arrays

Arrays 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', ['socket_id' => $socket_id]);
$batch = [];
$batch[] = ['channel' => 'my-channel', 'name' => 'my_event', 'data' => ['hello' => 'world'], ['socket_id' => $socket_id]];
$batch[] = ['channel' => 'my-channel', 'name' => 'my_event', 'data' => ['myname' => 'bob'], ['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', ['info' => 'subscription_count']);
$subscription_count = $result->channels['my-channel']->subscription_count;
$batch = [];
$batch[] = ['channel' => 'my-channel', 'name' => 'my_event', 'data' => ['hello' => 'world'], 'info' => 'subscription_count'];
$batch[] = ['channel' => 'presence-my-channel', 'name' => 'my_event', 'data' => ['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', [], true);

Authenticating users

To authenticate users on Pusher Channels on your application, you can use the authenticateUser function:

$pusher->authenticateUser('socket_id', 'user-id');

For more information see authenticating users.

Authorizing Private channels

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

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

For more information see authorizing users.

Authorizing Presence channels

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

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

For more information see authorizing users.

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_received = $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 authorization 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,
        [
            '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 a mixture of unencrypted and encrypted channels in a call to trigger, e.g.

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

$pusher->trigger(['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 the channel authorization endpoint in your JS app when creating the Pusher object:

var pusher = new Pusher("app_key",
  // ...
  channelAuthorization: {
    endpoint: "/presenceAuth.php",
  },
);

Next, create the following in presenceAuth.php:

<?php

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

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(json_encode('no-one is logged in'));
}

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

echo $pusher->authorizePresenceChannel($_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->getChannelInfo($name);

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

$info = $pusher->getChannelInfo('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->getChannelInfo('presence-channel-name', ['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->getChannelInfo('presence-channel-name', ['info' => 'subscription_count']);
$subscription_count = $info->subscription_count;

Get a list of application channels

$pusher->getChannels();

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

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

Get a filtered list of application channels

$pusher->getChannels(['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->getChannels(['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', ['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. Be warned: this approach consumes (number of channels + 1) messages!

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

Get user information from a presence channel

$results = $pusher->getPresenceUsers('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: https://www.opensource.org/licenses/mit-license.php

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

pusher-http-php's People

Contributors

allejo avatar benjaco avatar benjamin-tang-pusher avatar benpickles avatar damdo avatar grahamcampbell avatar hamchapman avatar it-can avatar jameshfisher avatar jpatel531 avatar kn100 avatar koozza avatar leggetter avatar lukabratos avatar mdpye avatar mmachatschek avatar pavlakis avatar pusher-ci avatar ruudk avatar sonologico avatar squeeks avatar stewartmalik avatar stof avatar topliceanu avatar vinkla avatar vivangkumar avatar willsewell avatar xico2k avatar zackkitzmiller avatar zimbatm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pusher-http-php's Issues

Add WebHooks helper

I'd like to bring this library up to feature parity with pusher-gem where possible.

Add cluster config option support

A cluster ID (eu/us-east2) and the URL is formed for the developer. This is how things work across all recently libraries.

$options = array('cluster' => 'eu');
$pusher = new Pusher('app-id', 'app-key', 'app-secret', $options);

The HTTP API ($baseUrl) will be:

https://api-eu.pusher.com

If `` were provided as the cluster ID then the URL would be:

https://api-useast2.pusher.com

Async support

Relevant issues: #99, #95

Looks to me like this SDK is semi-dead, so I am not expecting much.

Reuse existing cUrl connections

Do not close the cURL handler after request, so that it could reuse the existing connection.

Example:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,"http://api.pusherapp.com");
curl_setopt($ch, CURLOPT_VERBOSE, true);

curl_exec ($ch);
curl_exec ($ch);

Output:

* Rebuilt URL to: http://api.pusherapp.com/
* Hostname was NOT found in DNS cache
*   Trying 184.73.245.186...
* Connected to api.pusherapp.com (184.73.245.186) port 80 (#0)
> GET / HTTP/1.1
Host: api.pusherapp.com
Accept: */*

< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
* Server thin is not blacklisted
< Server: thin
< Content-Length: 11
< Connection: keep-alive
< 
Pusher API
* Connection #0 to host api.pusherapp.com left intact
* Found bundle for host api.pusherapp.com: 0x9f724b0
* Re-using existing connection! (#0) with host api.pusherapp.com <-- !!!
* Connected to api.pusherapp.com (184.73.245.186) port 80 (#0)
> GET / HTTP/1.1
Host: api.pusherapp.com
Accept: */*

< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
* Server thin is not blacklisted
< Server: thin
< Content-Length: 11
< Connection: keep-alive
< 
Pusher API
* Connection #0 to host api.pusherapp.com left intact

Output for same code but using curl_close($ch); between requests:

* Rebuilt URL to: http://api.pusherapp.com/
* Hostname was NOT found in DNS cache
*   Trying 54.225.207.125...
* Connected to api.pusherapp.com (54.225.207.125) port 80 (#0)
> GET / HTTP/1.1
Host: api.pusherapp.com
Accept: */*

< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
* Server thin is not blacklisted
< Server: thin
< Content-Length: 11
< Connection: keep-alive
< 
Pusher API
* Connection #0 to host api.pusherapp.com left intact
* Rebuilt URL to: http://api.pusherapp.com/
* Hostname was found in DNS cache
*   Trying 54.225.207.125...
* Connected to api.pusherapp.com (54.225.207.125) port 80 (#1)
> GET / HTTP/1.1
Host: api.pusherapp.com
Accept: */*

< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
* Server thin is not blacklisted
< Server: thin
< Content-Length: 11
< Connection: keep-alive
< 
Pusher API
* Connection #1 to host api.pusherapp.com left intact

new-lib: FileAdapter and SSL issue

make test returns the following error on my system:

1) Pusher\Tests\FileAdapterTest::testRequest
Notice: Undefined index: _SERVER in /Users/zimbatm/code/github.com/pusher/pusher-http-php/vendor/phpunit/phpunit/src/Util/Filter.php on line 28
Pusher\Exception\AdapterException: file_get_contents(https://pusher.com): failed to open stream: operation failed

/Users/zimbatm/code/github.com/pusher/pusher-http-php/src/Http/FileAdapter.php:73
/Users/zimbatm/code/github.com/pusher/pusher-http-php/tests/FileAdapterTest.php:38
/Users/zimbatm/code/github.com/pusher/pusher-http-php/vendor/phpunit/phpunit/phpunit:36

However SSL seem to be enabled and stream_get_contents() to support including remote files:

$ php -a
Interactive shell

php > var_dump(stream_get_wrappers());
array(12) {
  [0]=>
  string(5) "https"
  [1]=>
  string(4) "ftps"
  [2]=>
  string(13) "compress.zlib"
  [3]=>
  string(14) "compress.bzip2"
  [4]=>
  string(3) "php"
  [5]=>
  string(4) "file"
  [6]=>
  string(4) "glob"
  [7]=>
  string(4) "data"
  [8]=>
  string(4) "http"
  [9]=>
  string(3) "ftp"
  [10]=>
  string(4) "phar"
  [11]=>
  string(3) "zip"
}
php > var_dump(ini_get('allow_url_fopen'));
string(1) "1"
php > var_dump(extension_loaded('openssl'));
bool(true)

If I change the test domain to be google.com or github.com I get the same error.
Changing to plain HTTP doesn't have the same issue.

DNS resolving timeouts

Sorry, not really sure where to put this.

We are using the encrypted eu cluster.

Occasionally we are having errors with not being able to send events to Pusher.

After setting up some custom logging:

/*
         * Create a custom logger that throws exceptions we can do something with.
         */
        $this->pusher->set_logger(new class() {
            public function log(string $message) {

                if (\Core\Strings::startsWith($message, "Pusher: ERROR: exec_curl error:")) {
                    throw new Exception(str_replace("Pusher: ERROR: exec_curl error: ", "", $message));
                }

                if (\Core\Strings::startsWith($message, "Pusher: INFO: exec_curl response: ")) {

                    if (strpos($message, "[status] => 20") === false && preg_match("!\\[body] => (.*)!", $message, $matches)) {
                        throw new Exception($matches[1]);
                    }
                }
            }
        });

We now know what the exact error is that we are getting:

Resolving timed out after 5514 milliseconds

We have this issue about 50 times per month. We are sending about 120K messages per day so it's not very frequent but still more than we would like.

We have many dozens of suppliers integrated and Pusher is the only one with resolving timeouts.

Yes, our timeout is set to 5 seconds (else it wouldn't really be real time). Our servers are located in Amsterdam close to the AIX.

Drop PHP 5.2 Support

I think we should bump the minimum supported php version to 5.3.3, or even better, 5.4.0.

Both php 5.2 and 5.3 are not maintained anymore by the php core team so it makes no sense to support them. Even php 5.4 is losing support soon.

Add StyleCI Support

What about adding https://styleci.io/ support? Then we will get syntax checks on all commits and PRs made to this repository.

This is the guide to add StyleCI support:

  1. Sign up at https://styleci.io/

  2. Go to the repositories page https://styleci.io/account#repos

  3. Enable this repository.

  4. Press Show Analysis and then Settings.

  5. Add the following settings:

    enabled:
      - unalign_double_arrow
    
    disabled:
      - psr0
      - align_double_arrow
      - phpdoc_align
  6. Press Save Configuration.

  7. Press Analyze Now.

This has to be done by the owner of the repository.

Retrieve History

Hi Guys,

Pls help me function to get histoty of chanel?

Thank you.

Fatal error with socket_auth, PHP 7.1

Fatal error: Cannot declare class PusherException (name already in use) when using socket_auth() on PHP 7.1.0.

Code to reproduce:

<?php
$pusher = new Pusher($pusher_key, $pusher_secret, $pusher_app_id);
echo $pusher->socket_auth($_POST['channel_name'], $_POST['socket_id']); ?>

Example output:

{"auth":"f9514363b770207e2644:0072c281df9b3a56e9b20ed498b3eefc19e0fa7b50252795bbd26c3f587360f0"}
Fatal error: Cannot declare class PusherException, because the name is already in use in pusher.php on line 26

I double-checked that this error was not because of my own code. Other pusher functions like sending a message are 100% working.

I guess this is because of namespaces changes in PHP 7.1...? Is there any way to fix this without breaking compatibility with other versions?

Namespaces error

Our build process throws the following exception

PHP Fatal error:  Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "Pusher" from the global namespace.
Did you forget a "use" statement for "Pusher\Pusher"? in /builds/acme/vendor/laupifrpar/pusher-bundle/DependencyInjection/PusherFactory.php:26
Stack trace:
#0 /tmp/test/appTestDebugProjectContainer.php(5358): Lopi\Bundle\PusherBundle\DependencyInjection\PusherFactory::create(Array)
#1 /builds/acme/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(311): appTestDebugProjectContainer->getLopiPusher_PusherService()
#2 /tmp/test/appTestDebugProjectContainer.php(8112): Symfony\Component\DependencyInjection\Container->get('lopi_pusher.pus...')
#3 /builds/acme/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(311): appTestDebugProjectContainer->getAcme_Entity_AvailabilitySubscriberService()
#4 /tmp/test/appTestDebugProjectContainer.php(2830): Symfony\Component\DependencyInjection\Container->get('scri in /builds/acme/vendor/laupifrpar/pusher-bundle/DependencyInjection/PusherFactory.php on line 26

The laupiFrpar/LopiPusherBundle does not have the 3.0.0 dependency though:

"pusher/pusher-php-server": ">=2.2.1"

... so, maybe this can be fixed and released as 2.6.5 so the bundle does not break.

get user info from presence channel

How can we receive the user info that was provided in our auth endpoint when querying a presence channel? In auth, I return user info:

        $userInfo = array(
            'firstName' => $user->first_name,
            'lastName' => $user->last_name,
            'email' => $user->email,
            'id' => $user->id,
        );
        return $this->pusher->presence_auth($this->request->post('channel_name'), $this->request->post('socket_id'), $user->id, $userInfo);

When I later call

$pusher->get('/channels/presence-1234/users')

Only the user IDs are returned.

PSR-2

Would you accept a PR to move to PSR-2?

Provide a way to asynchronously trigger events

This is an issue to keep track of the demand for triggering event asynchronously.

There are a couple of pull requests to add this functionality but neither provide any tests. See #4 and #11.

We're looking at sorting out a number of libraries so I'm cleaning out some older issues.

StyleCI Not Enabled Anymore

StyleCI requires the connected user to be an admin on the repo. The connected user is not an admin anymore so StyleCI has disabled itself.

Consider refactoring logging to use PSR-3

The logging functionality is useful but pretty crude. Most importantly, there's no distinction between "log levels". It would be helpful, for example, to distinguish between basic informational event logging and error conditions (such as a failed trigger()).

The best way to do this would be by requiring that the $pusher->logger object implements the LoggerInterface specified in PSR-3:
http://www.php-fig.org/psr/psr-3/

If you're open to this it's quite easy to do and I'd be happy to provide a pull request.

Thanks,
Adam

The documentation is broken for triggerBatch

Dear Team,

I mentioned the triggerBatch function is not working, based on the example:

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

The problem with the 'event' key, it should be 'name' based on your documentation : https://pusher.com/docs/rest_api

This snippet is working like charm:

$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);

Cleanup branches?

Right now there is a lot of branches hanging around. This makes it hard to understand which branch is active and not. Maybe we can simplify them to just develop and master?

Merge new-lib branch

@zimbatm made a start on a new version of the pusher-http-php library (https://github.com/pusher/pusher-http-php/tree/new-lib) and the branch has a fair amount of people using it, notably because it lets people specify the host / cluster that they want to publish to, which the current version (on master) did not let you do for some time. That's not the only improvement though.

We should decide what we want to do with the new-lib branch and potentially make it the new version of the library on master, and release a new version.

socket_auth isn't providing correct data

I am trying to use this library to set up authentication for my iOS application, but am getting stuck authorizing. Here is the code that I am using to generate my hash:

socket_auth($_POST['channel_name'], $_POST['socket_id']); ?>

And this is the response shown in the Pusher debug console:

Invalid signature: Expected HMAC SHA256 hex digest of 44503.19289639:private-test-channel, but got 238c4f523215b154d06646940bf3b763e2e4934c3a61d8c0fe3f654f37f2695c

Am I missing something really stupid?

Pusher trigger appears too slow 500ms

I too am facing this same problem, I was expecting Pusher to be faster than this, 500ms here.. I'm not impressed Pusher.. The world operates faster than 500ms these days.. just ask google.
I say Pusher needs to be at to 80ms or faster per trigger! otherwise whats the point.

Invalid PHPDoc and typo

The PHPDoc for dome of the functions is outdated or incorrect. Some examples:

  • $request_method is missing
/**
     *  Build the required HMAC'd auth string
     *
     *  @param string $auth_key
     *  @param string $auth_secret
     *  @param string $request_path
     *  @param array $query_params
     *  @param string $auth_version [optional]
     *  @param string $auth_timestamp [optional]
     *  @return string
     */
    public static function build_auth_query_string($auth_key, $auth_secret, $request_method, $request_path,
        $query_params = array(), $auth_version = '1.0', $auth_timestamp = null)
  • default value for $port should be an int
/**
    * ...
    * @param string $auth_key
    * @param string $secret
    * @param int $app_id
    * @param bool $debug [optional]
    * @param string $host [optional]
    * @param int $port [optional]
    * @param int $timeout [optional]
    */
    public function __construct( $auth_key, $secret, $app_id, $debug = false, $host = 'http://api.pusherapp.com', $port = '80', $timeout = 30 )
  • $channels is missing
/**
    * Trigger an event by providing event name and payload. 
    * Optionally provide a socket ID to exclude a client (most likely the sender).
    *
    * @param array $channel An array of channel names to publish the event on.
    * @param string $event
    * @param mixed $data Event data
    * @param int $socket_id [optional]
    * @param bool $debug [optional]
    * @return bool|string
    */
    public function trigger( $channels, $event, $data, $socket_id = null, $debug = false, $already_encoded = false )

Tagged releases

It would be really nice to see tagged releases that are in sync with the JS version. That way I can stick my project to a specific JS + PHP version.

user_info supplied to presence subscription is invalid

Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"user_info supplied to presence subscription is invalid - if supplied it must be a type of hash"}}}

What type of hash does the library expect?

Constructor signature - new Pusher(...)

We want to keep the constructor as simple as possible. I'd suggest the use of the current Config object adds additional and unnecessary complexity.

A key part of doing this will be providing default values for things that were otherwise extracted from the URL:

  • Base URL
  • Encrypted (HTTP or HTTPS) - not actually part of the current Config, but probably should be

My vote is for one of the following:


1. Directly passing required parameters as arguments

$pusher = new Pusher('my-app-id', 'my-app-key', 'my-app-secret');

Additional options are added by a 4th options parameter:

$pusher = new Pusher('my-app-id', 'my-app-key', 'my-app-secret', array('encrypted' => true));

2. Using an Associative Array with named parameters

$pusher = new Pusher(array(appId => 'id_value', appKey' => 'key_value', 'appSecret' => 'secret_value', ...);

Optional parameters are just added to the array:

$pusher = new Pusher(array(appId => 'id_value', appKey' => 'key_value', 'appSecret' => 'secret_value', 'encrypted' => true);

The benefit of this approach is that it reduces the changes of getting key and secret mixed up.


What do others think? @zimbatm

More Intuitive Error Message When the Response Status Code Is 0

Hi,

Someone I spoke to on ZenDesk mentioned that when running the following code:

<?php
 require('Pusher.php');

 $options = array(
     'encrypted' => true
 );
 $pusher = new Pusher(
     'xxx',
     'xxx',
     'xxx',
     $options
);

 $data['message'] = 'hello world';
 $pusher->trigger('test_channel', 'my_event', $data);
?>

... He or she received the following response:

array(2) { ["body"]=> bool(false) ["status"]=> int(0)

A status code of 0 is quite pecuilar, no?

@jameshfisher and I did some research and found this StackOverflow answer, which states:

If you connect with the server, then you can get a return code from it, otherwise it will fail and you get a 0. So if you try to connect to "www.google.com/lksdfk" you will get a return code of 400, if you go directly to google.com, you will get 302 (and then 200 if you forward to the next page... well I do because it forwards to google.com.br, so you might not get that), and if you go to "googlecom" you will get a 0 (host no found), so with the last one, there is nobody to send a code back.

I have asked the user to enable debugging and to report back. In the meantime, @jameshfisher suggested that I open an issue requesting a more intuitive error in the case that the status is 0.

Add encrypted configuration option

$options = array('encrypted' => true);
$pusher = new Pusher('app-id', 'app-key', 'app-secret', $options);

The default for this options should be true and thus the URL should be HTTPS by default.

Addition of namespace breaks Laravel integration (Error: Class Pusher not found)

Since Laravel (Specifically Illuminate Broadcaster) tightly couples with this integration library, it is referring to Pusher without taking into account the introduction of a namespace.

The simplest workaround is simply change the references so that they are correct - a user has created an automation for this task here: https://stackoverflow.com/questions/45052853/class-pusher-not-found

Another workaround is just to continue using the previous version of this lib until Laravel update their end.

Do not send events [ Unknown auth_key]

I am using the following code:

`require('pusher-http-php-master/lib/Pusher.php');
error_reporting(E_ALL);
$app_id = '*'; 
$app_key = '*';
$app_secret = '*';

class MyLogger {
  public function log( $msg ) {
    print_r( $msg . "<br />" );
  }
}
$pusher = new Pusher($app_key, $app_secret, $app_id);
$logger = new MyLogger();
$pusher->set_logger( $logger );
$data['message'] = 'hello world';
$result = $pusher->trigger('test_channel', 'my_event', array( 'hello' => 'world' ));
$logger->log( "---- My Result ---" );
$logger->log( $result );`

And the answer I have is:

Pusher: ->trigger received string channel "test_channel". Converting to array. Pusher: create_curl( http://api.pusherapp.com:80/apps/*/events?auth_key=*&auth_signature=*&auth_timestamp=*&auth_version=1.0&body_md5=*) Pusher: trigger POST: {"name":"my_event","data":"{\"hello\":\"world\"}","channels":["test_channel"]} Pusher: exec_curl response: Array ( [body] => Unknown auth_key [status] => 400 ) ---- My Result ---

What am I doing wrong?

What I want is to send notifications from the server.

The 2.2.1 version broke compatibility with PHP 5.3 and lower

The composer.json file says that your library supports PHP 5.2+. However, the fix done in #40 uses a private function as callback for array_walk, which is only working on PHP 5.4+.

There is 3 ways to fix it:

  • bump the minimal version to 5.4 (but this means that any 5.3 user is forced to use a vulnerable version of the library)
  • change the validate method to be public (and documenting it as internal with @internal)
  • use a foreach loop over channels instead.

Error on `composer install`

  [RuntimeException]
  File at "/var/www/api/vendor/pusher/pusher-php-server/lib//Pusher.php" does not exist, check your classmap definitions

Drop PHP 5.3 and 5.4 Support

IMO we should drop PHP 5.3 and 5.4 support and go with 5.5.9 as the minimum requirement. PHP 5.4 isn't supported anymore, it wont receive any security fixes as of september 2015.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.