I'm making a POC with Lumen and Vue.JS. For now it just has to send a "hello world" message from the Lumen back-end to the Vue.JS front-end (which works). I have made an event which is triggered upon loading the page like this:
public function sendMessage(Request $request)
{
event(new MessageEvent('hello world'));
}
The MessageEvent looks like this (got this from the Pusher getting started help):
class MessageEvent extends Event implements ShouldBroadcast
{
/**
* Create a new event instance.
*
* @return void
*/
public $message;
public function __construct($message)
{
$this->message = $message;
}
public function broadcastOn()
{
return ['my-channel'];
}
public function broadcastAs()
{
return 'my-event';
}
}
This part is working, since I'm receiving this in the Vue.JS application:
Pusher : : ["Event recd",{"event":"my-event","channel":"my-channel","data":{"message":"hello world"}}]
Now comes the problem when i check the queue log. triggered with php artisan queue:listen
, I see the following:
[2021-03-14 11:57:03][Bh7373O9EETAZc39M2RCSPmUTjwSbSmL] Processing: App\Events\MessageEvent
[2021-03-14 11:57:04][Bh7373O9EETAZc39M2RCSPmUTjwSbSmL] Failed: App\Events\MessageEvent
When I check the Lumen log files it says the following:
[2021-03-14 11:43:12] local.ERROR: Undefined property: stdClass::$channels {"exception":"[object] (ErrorException(code: 0): Undefined property: stdClass::$channels at /var/www/vendor/pusher/pusher-php-server/src/Pusher.php:538)
So I went ahead and checkt the Pusher.php file:
536: $result = json_decode($response['body']);
537:
538: if ($result->channels) {
539: $result->channels = get_object_vars($result->channels);
540: }
I decided to check what $response
was, it gives the following:
[2021-03-14 11:57:04] local.INFO: array (
'body' => '{}',
'status' => 200,
)
Of course it can't get to $result->channels
if response["body"]["channels"]
doesn't exist.
When I go and check the Pusher API reference it says the following:
Which would mean that the body should indeed contain a JSON response. But when I scroll a bit further I see this:
Which should mean you don't have to set the info parameter, since it's optional and experimental.
[EXPERIMENTAL] If the info parameter is sent, then it returns a hash of unique channels that were triggered to. The hash maps from channel name to a hash of attributes for that channel (may be empty).
The response it expects with the info parameter set is this:
{
"channels": {
"presence-foobar": {
"user_count": 42,
"subscription_count": 51
},
"presence-another": {
"user_count": 123,
"subscription_count": 140
},
"another": {
"subscription_count": 13
}
}
}
Which is the channels
object asked for.
My question is, did I miss something or is this a bug from Pusher? I'm really breaking a leg on this one so I hope someone can help me out.
Pusher API reference: https://pusher.com/docs/channels/library_auth_reference/rest-api
Fix composer.json
I have created an issue on the PHP package: https://github.com/pusher/pusher-http-php/issues/295
It is true this version is broken, but the fix should be in the composer.json
file. Mine looked like this:
{
...
"require": {
...
"pusher/pusher-php-server": "5.0"
...
},
...
}
This means I specifically say that it should use version 5.0
. But now I won't get version 5.2
for example, which means I won't get patches. According to the people who answered my issue on Github, I should change my composer.json
and add a ^
in front of the version number so it does get the patches for that version. So it should be changed like this:
{
...
"require": {
...
"pusher/pusher-php-server": "^5.0"
...
},
...
}
Don't forget to run composer update
afterwards.
According to Graham Campbell on Github:
Anyone who puts
5.0
in theircomposer.json
file has made an error, since composer resolves this to the version5.0.0.0
and not the version constraint^5.0
.
Fix pusher.php (not recommended)
Another workaround would be to directly edit /vendor/pusher/pusher-php-server/src/Pusher.php
. Although not recommended, it does work.
536: $result = json_decode($response['body']);
537:
538: if ($result->channels) {
539: $result->channels = get_object_vars($result->channels);
540: }
This doesn't work since channels
doesnt exist in the result
object. It should check if the channels object exists first. You can do that by changing the above code to this:
536: $result = json_decode($response['body']);
537:
538: if (property_exists($result, 'channels')) {
539: $result->channels = get_object_vars($result->channels);
540: }