【发布时间】:2021-05-03 01:52:56
【问题描述】:
我正在尝试编写一个具有与 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 函数定期轮询服务器,但如果可能的话,我肯定也想直接从 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 并没有很好地记录到我真正想要的最后,我希望我可以通过这个连接获得一些稳定性,而不是不得不做一些丑陋的事情,比如强制重启。
【问题讨论】:
标签: javascript php laravel websocket laravel-echo