【问题标题】:Laravel echo/pusher not sending ping when receiving dataLaravel echo / pusher在接收数据时不发送ping
【发布时间】:2021-07-11 18:30:09
【问题描述】:

我正在运行 laravel websocket 并通过 wss 建立连接。

我在服务器上运行命令,命令记录在一个文件中。每行也通过 websocket 发送到前端,以便我查看。每个 laravel-command 都有自己的文件和广播频道。

命令记录器:

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

在 Vue.js 中,我使用 Echo(实现 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);
     });

我遇到的问题仅在命令发送大量消息以回显时发生。

在正常速率下,消息之间会出现一些暂停,echo 会进行乒乓球,并且连接会继续接收消息。

在更高的消息速率下,似乎 echo 没有发送乒乓球,我的套接字默默地停止接收数据。在它停止接收后,它开始乒乓球,好像什么都没发生一样。服务器和客户端都没有断开连接。

Websocket 消息(注意它在 205000 处停止,没有错误并恢复乒乓球):

实际命令输出(在 230000 并且仍在运行):

如果我刷新页面,我会再次收到消息。

我直接更新了websockers:serve 命令(vendor/beyondcode/laravel-websockets/src/Console/Commands/StartServer.php)并禁用了pongtracker:

protected function configurePongTracker()
{
    //$this->loop->addPeriodicTimer(10, function () {
    //    $this->laravel
    //        ->make(ChannelManager::class)
    //        ->removeObsoleteConnections();
    //});
}

然后我重新启动了 websocket 并再次尝试。这一次,无论我发送消息的速度有多快,echo 都会继续接收消息。

TL;DR:

我的结论是 echo 应该在从服务器接收消息之间进行乒乓球,因为目前它似乎无法这样做,并且 websocket 最终会清除连接而不会断开连接。如何强制 echo 进行乒乓球,或确保服务器不清理连接而不冒连接失控的风险?

更新 1:

我已经深入研究了Startserver.php 文件并发现了这个:

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()
    );
}

这就解释了为什么我停止接收消息,但没有断开连接。它只是取消订阅我正在收听的频道(在前端看不到)并保持连接。

我还创建了一个issue on github(laravel/echo),因为我确实认为这是不受欢迎的行为。我只是不确定问题出在 echo 中,还是在 pusher js 中。

【问题讨论】:

    标签: laravel echo laravel-8 pusher-js laravel-websockets


    【解决方案1】:

    我经历过。检查您的频道名称和类型,并确保您有权访问。另外,请检查是否有其他 js 文件干扰您的 app.js 文件,就像我发生的那样。检查这个laracasts question out

    【讨论】:

    • 我相信我的访问是正确的,我的广播/授权是成功的
    • 我还验证了我只注入了一次app.js(它是一个单页应用程序)并尝试了您提到的问题中的建议,但没有成功。如果您有更多提示,我很乐意尝试 :)
    猜你喜欢
    • 2018-02-17
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多