Laravel Pusher broadcast data as array - php

When trying to send a request to Pusher from my controller, I would like to see a array in the channel as follows:
[3,"e7563ce0-c1ef-499d-9919-9a3d2a3ff523",{"status":"Accepted","currentTime":"2022-06-22T13:16:05+0000","interval":30}]
The way I am sending an request looks like this (ChargerController.php)
$pusher = new Pusher(
$charger->identifier,
$charger->identifier,
$charger->identifier,
[
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
'encrypted' => false,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http',
]
);
$pusher->trigger($charger->getOcppChannelName(), 'Reset', json_encode([
OCPPMessageService::OCPP_MESSAGE_TYPE_CALL,
Uuid::uuid4(),
'Reset',
['type' => ChargerResetTypeEnum::HARD],
]), [], true);
For some reason this gives the following result:
{"0":2,"1":"1a00b2f6-5af9-4a56-bd1c-723b6669380d","2":"Reset","3":{"type":"Hard"}}
I would like to have the data be an array, without any keys, as the system we are interacting with doesn't understand an object with keys. Even in the vendors we weren't able to find the reason it does this.

Related

Laravel WebSockets cannot send event

I'm having troubles with dispatching events on my local Laravel configuration.
I'm trying to dispach it directly from the dashboard http://localhost:8000/laravel-websockets, but it always return Error sending event. Even if it is connecting to the dashboard.
My config looks:
.env file:
QUEUE_CONNECTION=database
QUEUE_DRIVER=sync
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=local
PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_APP_CLUSTER=mt1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_HOST=127.0.0.1
Configuration in boradcasting.php:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'host' => env('PUSHER_HOST', 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
Configuration in websockets.php:
'apps' => [ [
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'path' => env('PUSHER_APP_PATH'),
'capacity' => null,
'enable_client_messages' => false,
'enable_statistics' => true,
],
],
I did enable all providers, and still not dispatching even from the dashboard.
I tried to create event and dispatch from the controller, but still not working.
Any ideas what could cause it?
Edit: just noticed in dashboard a message like:
Channels current state is connected

Laravel WebSockets: Illuminate \ Broadcasting \ BroadcastException: No Message and net::ERR_CERT_AUTHORITY_INVALID

I've been trying to get this WebSocket package running on my local Laravel project for about a week now and I can't seem to find a solution to the issue. I've followed the documentation, multiple tutorials and answers on Stack Overflow / Github, but I keep getting the same error. These are my configurations:
.env:
PUSHER_APP_ID=anyId
PUSHER_APP_KEY=anyKey
PUSHER_APP_SECRET=anySecret
PUSHER_APP_CLUSTER=eu
config/broadcasting:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
'encrypted' => false,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http',
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
]
],
]
config/websockets:
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'path' => env('PUSHER_APP_PATH'),
'capacity' => null,
'enable_client_messages' => false,
'enable_statistics' => true,
],
],
resources/js/bootstrap.js:
There is also WebsocketEvent and controller which calls the broadcasting of the event, I haven't included them to keep this shorter.
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'anyKey',
encrypted: false,
wsHost: window.location.hostname,
wsPort: 6001,
disableStats: true,
enabledTransports: ['ws', 'wss']
});
window.Echo.channel('DemoChannel')
.listen('WebsocketEvent', (e) => {
console.log(e);
});
Front-end error: This only seems to be fine when I set enabledTransports: ['wss'] which represents the secure connection but default of enabledTransports: ['ws'] doesn't.
Back-end error: Always fails.
As you can see, I've added the curl options as recommended on https://github.com/beyondcode/laravel-websockets/issues/109 and I've set encrypted: false. Overall, I believe it is a certificate issue which is beyond my full comprehension but the tutorials I followed seem to get it working perfectly on their local environment without SSL certificates, etc. Also, it seems like other developers who are having similar issues are not getting answered (example), which is why I am posting this. Any help would be appreciated, thank you.

Laravel websockets failed to connect in pusher

When I run my project, I got an exception error but it does not have a clear message. I only have this kind of the main body error
I can access websocket admin page at http://127.0.0.1:8000/laravel-websockets but when i go http://127.0.0.1:8000/ i got errors below.
The following error was encountered while trying to retrieve the URL: http://127.0.0.1:6001/apps/995591/events?
Connection to 127.0.0.1 failed.
The system returned: (111) Connection refused
The remote host or network may be down. Please try the request again.
Generated Tue, 05 May 2020 17:12:03 GMT by proxyserversetup-s-1vcpu-1gb-sgp1-07 (squid/3.5.27)
I followed every single thing in the docs from this link
Here are some of my config
broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => false,
'useTLS' => true,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http',
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
],
],
],
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=inventory
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=995591
PUSHER_APP_KEY=644a4ac1988060882370
PUSHER_APP_SECRET=739696537f4fb23b8fcd
PUSHER_APP_CLUSTER=ap1
I am using laravel 6.x and the current version for laravel websockets.
Is it my ISP cause the error?
I had something similar to this happen to me.
If you are using localhost, change
'useTLS' => true,
to false
'useTLS' => false,
It should be in your broadcasting.php file
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
],
],
....
Making sure you set scheme to https and use 'useTLS' => true then setting up curl_options like below if you set up the paths for SSL certificate & private key.
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
],
Verify the PUSHER_PORT data in the .env file:
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6379
Verify using CLI in the docroot with artisan command for web socket:
php artisan websockets:serve --port=6379

Fusio api cache configuration

Googled and tried,but failed.
How to configure Fusio to use redis.?
//'psx_cache_factory' => null,
This doesnt work:
'psx_cache_factory' => 'redis'
This also doesnt work:
'psx_cache_factory' => 'redis://127.0.0.1:6379',
Answered by developer.
Github
'psx_cache_factory' => function($config, $namespace){
$client = new \Predis\Client([
'scheme' => 'tcp',
'host' => '10.0.0.1',
'port' => 6379,
]);
return new \Doctrine\Common\Cache\PredisCache($client);
},

Laravel + Redis Cache via SSL?

I am trying to connect to Redis with predis 1.1 and SSL, using information https://github.com/nrk/predis, where in the example the following configuration is used:
// Named array of connection parameters:
$client = new Predis\Client([
'scheme' => 'tls',
'ssl' => ['cafile' => 'private.pem', 'verify_peer' => true],
]);
My Laravel configuration looks like below:
'redis' => [
'client' => 'predis',
'cluster' => env('REDIS_CLUSTER', false),
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'options' => [
'cluster' => 'redis',
'parameters' => ['password' => env('REDIS_PASSWORD', null)],
'scheme' => 'tls',
],
],
Unfortunately I am getting the following error:
ConnectionException in AbstractConnection.php line 155:
Error while reading line from the server. [tcp://MY_REDIS_SERVER_URL:6380]
Suggestions are appreciated :)
I was able to get it to work!
You need to move 'scheme' from 'options' to 'default':
My working config:
'redis' => [
'client' => 'predis',
'cluster' => env('REDIS_CLUSTER', false),
'default' => [
'scheme' => 'tls',
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'options' => [
'parameters' => ['password' => env('REDIS_PASSWORD', null)],
],
],
Note: I had also removed the 'cluster' option from 'options', but I don't suspect this to be the make-or-break with this problem.
In my final-final config, I changed it to: 'scheme' => env('REDIS_SCHEME', 'tcp'), and then defined REDIS_SCHEME=tls in my env file instead.
Tested with AWS ElastiCache with TLS enabled.
Edit:
The above config only works with single-node redis. If you happen to enable clustering and TLS then you'll need a different config entirely.
'redis' => [
'client' => 'predis',
'cluster' => env('REDIS_CLUSTER', false),
// Note! for single redis nodes, the default is defined here.
// keeping it here for clusters will actually prevent the cluster config
// from being used, it'll assume single node only.
//'default' => [
// ...
//],
// #pro-tip, you can use the Cluster config even for single instances!
'clusters' => [
'default' => [
[
'scheme' => env('REDIS_SCHEME', 'tcp'),
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DATABASE', 0),
],
],
'options' => [ // Clustering specific options
'cluster' => 'redis', // This tells Redis Client lib to follow redirects (from cluster)
]
],
'options' => [
'parameters' => [ // Parameters provide defaults for the Connection Factory
'password' => env('REDIS_PASSWORD', null), // Redirects need PW for the other nodes
'scheme' => env('REDIS_SCHEME', 'tcp'), // Redirects also must match scheme
],
]
]
Explaining the above:
'client' => 'predis': This specifies the PHP Library Redis driver to use (predis).
'cluster' => 'redis': This tells Predis to assume server-side clustering. Which just means "follow redirects" (e.g. -MOVED responses). When running with a cluster, a node will respond with a -MOVED to the node that you must ask for a specific key.
If you don't have this enabled with Redis Clusters, Laravel will throw a -MOVED exception 1/n times, n being the number of nodes in Redis cluster (it'll get lucky and ask the right node every once in awhile)
'clusters' => [...] : Specifies a list of nodes, but setting just a 'default' and pointing it to the AWS 'Configuration endpoint' will let it find any/all other nodes dynamically (recommended for Elasticache, because you don't know when nodes are comin' or goin').
'options': For Laravel, can be specified at the top-level, cluster-level, and node option. (they get combined in Illuminate before being passed off to Predis)
'parameters': These 'override' the default connection settings/assumptions that Predis uses for new connections. Since we set them explicitly for the 'default' connection, these aren't used. But for a cluster setup, they are critical. A 'master' node may send back a redirect (-MOVED) and unless the parameters are set for password and scheme it'll assume defaults, and that new connection to the new node will fail.
Thank you CenterOrbit!!
I can confirm the first solution does allow Laravel to connect to a Redis server over TLS. Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured as single node and single shard.
I can also confirm the second solution does allow Laravel to connect to a Redis Cluster over TLS. Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured with "Cluster Mode Enabled", 1 shard, 1 replica per shard.
I was receiving the following error when I first tried to implement the cluster solution:
Error: Unsupported operand types
I missed the additional set of array brackets when I moved the "default" settings into the "clusters" array.
INCORRECT
'clusters' => [
'default' => [
'scheme' ...
]
]
CORRECT
'clusters' => [
'default' => [
[
'scheme' ...
]
]
]
I hope this saves someone else a bit of troubleshooting time.
The accepted solution by CenterOrbit worked for me, as I was using AWS I had to add tls:// in my .env
Laravel
tls://username:password#URL:PORT?database=0
Try it. It will work

Categories