会话断开后重新连接到 Laravel Echo 服务器

Reconnect to Laravel Echo server after session disconnection

我正在尝试编写一个 Web 应用程序,该应用程序具有与 laravel-echo-server 实例的持久回显连接,它需要检测断开连接并尝试正常重新连接。我现在试图克服的场景是用户的机器已经进入睡眠/重新唤醒并且他们的会话密钥已失效(回声服务器需要我们应用程序中的活动会话)。从 HTTP 角度检测这种情况已解决 - 我设置了一个常规的 keepAlive,如果该 keepAlive 检测到 400 级错误,它会重新连接并更新会话 auth_token.

当我的 Laravel 会话结束时,我无法从回声的角度判断发生了什么。我发现的最好的是我可以附加到 'disconnect' 事件,但只有在服务器端 laravel-echo-server 进程终止时才会触发,而不是会话无效:

        this.echoConnection.connector.socket.on('connect', function() {
            logger.log('info', `Echo server running`);
        })
        this.echoConnection.connector.socket.on('disconnect', function() {
            logger.log('warn', `Echo server disconnected`);
        });

在 laravel-echo-server 端,我可以看出连接已断开 - 它会显示此错误:

⚠ [7:03:30 PM] - 5TwHN2qUys5VEFP5AAAG could not be authenticated to private.1

我不知道如何从客户端以编程方式捕获此失败事件。有没有办法捕获它?同样,我可以告诉会话最终已经结束,因为我通过 http keepAlive 函数定期轮询服务器,但如果可能的话,我肯定也想直接从 echo 连接中判断,因为它以更高的自然速率轮询。

作为第二个(更重要的)问题,如果我检测到我的会话已终止,我应该如何回收回显连接(在我通过 HTTP 再次登录并获得新的 auth_token )?有什么具体的我应该打电话给/等吗?我在调用 disconnect() 然后从头开始重新建立连接时取得了一些成功,但我确实看到了如下错误:

websocket.js:201 WebSocket is already in CLOSING or CLOSED state.

这是我当前的(天真的)重新连接代码,这是我的初始连接代码,尝试断开连接首先钉在上面:

    async attemptEchoReconnect() {

        if (this.echoConnection !== null) {
            this.echoConnection.disconnect();
            this.echoConnection = null;
        }

        const thisConnectionParams = this.props.connections[this.connectionName];
        const curThis = this;

        this.echoConnection = new Echo({
            broadcaster: 'socket.io',
            host: thisConnectionParams.echoHost,
            authEndpoint: 'api/broadcasting/auth',
            auth: {
                headers: {
                    Authorization: `Bearer ` + thisConnectionParams.authToken
                }
            }
        });

        this.echoConnection.connector.socket.on('connect', function() {
            logger.log('info', `Echo server running`);
        })
        this.echoConnection.connector.socket.on('disconnect', function() {
            logger.log('warn', `Echo server disconnected`);
        });

        this.echoConnection.join('everywhere')
            .here(users => {
                logger.log('info', `Rejoined presence channel`);
            });

        this.echoConnection.private(`private.${this.props.id}`)
            .listen(...);

        setTimeout(() => { this.keepAlive() }, 120 * 1000);
    }

任何帮助都会非常有用 - 这些 API 没有很好地记录到我真正想要的结尾,我希望我可以通过这个连接获得一些稳定性,而不是必须做一些丑陋的事情,比如强制重启。

对于需要帮助解决此问题的任何人,我上面的 echo 重新连接代码似乎非常稳定,还有一个 keepAlive 函数来确定 HTTP 连接的状态。我仍然有点不确定我看到的控制台错误的来源,但我怀疑它们与睡眠周期中的连接丢失有关,这不是我特别担心的事情。

如果有人有任何想法,我仍然有兴趣听听其他想法。我有点倾向于相信回声连接的长期稳定性是可能的,尽管看起来您必须使用可用的工具主动监控它。