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

时间:2021-01-29 05:56:37

标签: javascript php laravel websocket laravel-echo

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

当我的 Laravel 会话结束时,我无法从回声的角度判断这是否发生了。我发现的最好的是我可以附加到“断开连接”事件,但只有在服务器端 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 函数定期轮询服务器,但如果可能的话,我肯定也想直接从回声连接中判断,因为它以更高的自然速率进行轮询。

作为第二个(更重要的)问题,如果我检测到我的会话已经死亡,我应该怎么做来回收回声连接(在我通过 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 并没有详细记录到我真正想要的最后,我希望我可以通过这种连接获得一些稳定性,而不必做一些丑陋的事情,比如强制重启。

1 个答案:

答案 0 :(得分:0)

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

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