I'm running a laravel websocket and have a connection over wss.
I am running commands on the server, and the commands are logged in a file. Each line is also sent over a websocket to the front-end so I can view it. Each laravel-command has it's own file and broadcast-channel.
Commandlogger:
class CommandLogger implements Logger {
public $commandname = '';
public $broadcast = false;
public function __construct($commandname, $broadcast = false) {
$this->commandname = Str::camel(Str::slug($commandname));
$this->broadcast = $broadcast;
}
function log($message) {
$message = Carbon::now()->format('Y-m-d H:i:s').": ".$message;
file_put_contents(storage_path("logs/commands/$this->commandname.log"), $message.PHP_EOL , FILE_APPEND | LOCK_EX);
if($this->broadcast) {
event(new CommandLogCreated($message, $this->commandname));
}
}
}
In Vue.js I listen with Echo(which implements pusherjs):
Echo.private('logs.commands.' + command)
.listen('.command-log:created', event => {
this.log[command] += event.message + "\n";
let splitLog = this.log[command].split("\n");
let splitLength = splitLog.length;
if(splitLength > 200) {
splitLog = splitLog.slice(splitLength - 200, splitLength);
}
this.log[command] = splitLog.join('\n');
this.trigger++;
})
.error(error => {
console.log(error);
});
The issue I'm experiencing only happens when the command is sending a lot of messages to echo.
At a normal rate, with some pauses between the messages, echo does the ping-pong and the connection remains receiving messages.
At higher message rates, is seems echo is not sending the ping-pong and my socket silently stops receiving data. After it stops receiving it starts ping-ponging as if nothing happend. No disconnect has occured on both server and client.
Websocket messages(notice it stops at 205000, gives no error and resumes ping-pong):
Actual command output(at 230000 and still running):
If I refresh the page, I will receive messages again.
I've updated the websockers:serve
command (vendor/beyondcode/laravel-websockets/src/Console/Commands/StartServer.php) directly and disabled the pongtracker:
protected function configurePongTracker()
{
//$this->loop->addPeriodicTimer(10, function () {
// $this->laravel
// ->make(ChannelManager::class)
// ->removeObsoleteConnections();
//});
}
Then I rebooted the websocket and tried again. This time, no matter how fast I was sending messages in, echo keeps receiving messages.
TL;DR:
My conclusion is that echo should ping-pong in between receiving messages from the server, because currently it seems to fail at doing so, and the websocket cleans the connection eventually without disconnecting. How can I either force echo to do the ping-pong, or make sure the server does not clean the connection without running the risk of having runaway connections?
Update 1:
I've been diving a little more into the Startserver.php
file and found this:
public function removeObsoleteConnections(): PromiseInterface
{
if (! $this->lock()->acquire()) {
return Helpers::createFulfilledPromise(false);
}
$this->getLocalConnections()->then(function ($connections) {
foreach ($connections as $connection) {
$differenceInSeconds = $connection->lastPongedAt->diffInSeconds(Carbon::now());
if ($differenceInSeconds > 120) {
$this->unsubscribeFromAllChannels($connection);
}
}
});
return Helpers::createFulfilledPromise(
$this->lock()->forceRelease()
);
}
So that explains why I stop receiving messages, but there is no disconnect. It just unsubscribes the channels I'm listening to silently(can't see this on front-end) and keeps the connection alive.
I've also created an issue on github(laravel/echo) because I do think this is unwanted behaviour. I'm just not sure if the issue lies within echo, or within pusher js.