Hi All,
I posted this over to the Reverb GitHub under "issues" but I wanted to post here as well to see if anyone has any insight.
Reverb Version
1.4.4
Laravel Version
11.37.0
PHP Version
8.4.2
Description
Hi Team,
I am a long time Laravel developer (since Laravel 5) and new to Reverb. You built an amazing product. I was using the old "Websockets" package and am now upgrading our system to Reverb. The "scaling" feature is what really caught my eye.
We have a production environment that I would consider advanced, but also something that I believe it going to come up as more and more customers move to Reverb.
We have 5 Redis servers deployed in production and are using Redis Sentinel to monitor them and at any one time one is the master and the others are replicas. If one goes down, Sentinel will promote another to master without any intervention. We have the Sentinels sitting behind a load balancer (HA Proxy).
We are using this package to implement Sentinel in Laravel:
https://github.com/Namoshek/laravel-redis-sentinel
It's a great package and essentially instead of using phpredis for the redis client you use "phpredis-sentinel". It just extends phpredis to work with Sentinel.
Our Laravel Redis configuration looks like this:
'redis' => [
'client' => 'phpredis-sentinel',
'driver' => 'redis',
'default' => [
'database' => 0,
'scheme' => 'tls',
'sentinel_host' => '*', // our host goes here
'sentinel_port' => 26379,
'sentinel_service' => '*', // our service goes here
'sentinel_timeout' => 0,
'sentinel_retry_interval' => 0,
'sentinel_read_timeout' => 0,
'sentinel_password' => '*', // our sentinel password goes here
'password' => '*', // our redis password goes here
'options' => [
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'allow_self_signed' => false,
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT,
]
]
],
...
This is working perfectly. We can read and write to redis from Laravel using either the Cache or Redis Facades (and all other aspects of the system that use Redis work perfectly).
When turning on the "scaling" in Reverb it blows up with a stack trace:
#0 /Users/rob/code/application/vendor/clue/redis-protocol/src/Parser/ResponseParser.php(39): Clue\Redis\Protocol\Parser\ResponseParser->readResponse()
#1 /Users/rob/code/application/vendor/clue/redis-protocol/src/Parser/ResponseParser.php(31): Clue\Redis\Protocol\Parser\ResponseParser->tryParsingIncomingMessages()
#2 /Users/rob/code/application/vendor/clue/redis-react/src/StreamingClient.php(55): Clue\Redis\Protocol\Parser\ResponseParser->pushIncoming('-NOAUTH Authent...')
#3 /Users/rob/code/application/vendor/evenement/evenement/src/EventEmitterTrait.php(143): Clue\React\Redis\StreamingClient->{closure:Clue\React\Redis\StreamingClient::__construct():53}('-NOAUTH Authent...')
#4 /Users/rob/code/application/vendor/react/stream/src/Util.php(71): Evenement\EventEmitter->emit('data', Array)
#5 /Users/rob/code/application/vendor/evenement/evenement/src/EventEmitterTrait.php(143): React\Stream\Util::{closure:React\Stream\Util::forwardEvents():70}('-NOAUTH Authent...')
#6 /Users/rob/code/application/vendor/react/stream/src/DuplexResourceStream.php(209): Evenement\EventEmitter->emit('data', Array)
#7 /Users/rob/code/application/vendor/react/event-loop/src/StreamSelectLoop.php(246): React\Stream\DuplexResourceStream->handleData(Resource id #1444)
#8 /Users/rob/code/application/vendor/react/event-loop/src/StreamSelectLoop.php(213): React\EventLoop\StreamSelectLoop->waitForStreamActivity(29549415)
#9 /Users/rob/code/application/vendor/laravel/reverb/src/Servers/Reverb/Http/Server.php(41): React\EventLoop\StreamSelectLoop->run()
#10 /Users/rob/code/application/vendor/laravel/reverb/src/Servers/Reverb/Console/Commands/StartServer.php(76): Laravel\Reverb\Servers\Reverb\Http\Server->start()
I did some troubleshooting and it looks like Reverb is trying to use it's own Redis client using a different package to setup the Pub/Sub and read/write to Redis which won't work in our environment.
The docs state:
Reverb will use the default Redis connection configured for your application.
When in fact (from what I can deduce) it's not really using the connection, it's just grabbing information from the default connection configuration and trying to create its own connection using that data (redis URL).
So, this all comes down to my question:
Can I create my own ServiceProvider or something -- I am not an expert on the inner workings of Laravel -- so that Reverb will use the existing Redis in our Laravel for all connections to Redis, not farm it out to another Redis client.
Or, maybe you can add a feature/flag such that it works this way by default, that seems logical that Reverb will just use the Redis we have configured as a default.
To me, this seems counterintuitive that Reveb would not be using the default Laraval connection (the actual connection, not the connection settings) since Reverb is a Laravel product, I would think it would use our default Redis connection out of the gate. It actually does not seem that the reverb.php config file should even have a "server" section as this is just Redis credentials that are already configured in Laravel as part of the Redis setup. Since Reverb scaling actually requires Redis to work, it seems like just "enabling" scaling would check if Redis is configured for Laravel and if not, it would fail.
Anyhow, if you would assist me (and others in the future) on how to essentially make Reverb use the Redis connection in our Laravel that would be greatly appreciated.
We are going to have N reverb servers sitting behind HA Proxy and it's critical that the scaling work so all of our reverb servers can talk to each other when new message are posted.
If Reverb can just use our configured Redis in Laravel we are done :)
Thanks!
-Rob
Steps To Reproduce
see above