Open rcbevans opened 1 year ago
I got the same error when use iOS15.0 WebView and iOS16.4.1 WebView.
UserAgent as follow
Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148')
Mozilla/5.0 (iPhone; CPU iPhone OS 16_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
but Its ok in iOS14.0.3(safari 14.4.2) Webview.
I have tried to use ua-parser-js
npm library to distinguish different os and webkit version, and emit close event by manual, the code snippet as follow:
import { UAParser } from 'ua-parser-js';
export class HocuspocusProviderWebsocket extends EventEmitter {
clientUA = new UAParser(window.navigator.userAgent)
getEngineName(): string {
return this.clientUA.getEngine().name?.toLowerCase() ?? '';
}
getOSName(): string{
const os = this.clientUA.getOS();
return os.name?.toLowerCase() ?? ''
}
getOSVersion(): number {
const os = this.clientUA.getOS();
return parseFloat(os.version ?? '0');
}
}
....
if (
this.getEngineName() === 'webkit' &&
this.getOSName() === 'ios' &&
this.getOSVersion() >= 15.0
) {
const payload = {
code: 4410,
reason: 'Client Connection Timeout',
}
this.emit("close", { event: payload })
}
the result is: iOS 15.0 is fine when turn off wifi, it can switch to cellular automatically. but iOS16 still hang and cannot receive 'close' event, that's very confusing :-(
Checklist
Describe the bug There is an open bug in Webkit in which it doesn't raise the correct onerror/onclose handlers when the network is lost/changes. y-websocket does not detect a loss of connectivity and therefore doesn't handle it appropriately. This means the client doesn't know that it is offline and all updates are fired off into the abyss causing user data loss without local persistence.
https://bugs.webkit.org/show_bug.cgi?id=247943 https://stackoverflow.com/questions/75869629/ios-websocket-close-and-error-events-not-firing
To Reproduce Steps to reproduce the behavior:
Expected behavior y-websocket should detect that connectivity has been lost and raise the appropriate connection lifecycle events so the user can be notified, and the underlying websocket recreated to re-establish a connection.
Environment Information
Additional context This is not a y-websocket issue but an underlying issue in Webkit; but it is a pretty devastating bug for any products using it since user data is lost without any warning.
I was forced to implement a custom heartbeat in my websocket packets and detect loss of connectivity so I could manually recreate the websocket to reestablish a connection. (There is also an issue here, since calling
provider.close()
does not clean up internal state because it relies on_ws.onclose
firing to do clean up, so it was necessary to manually clean up internal state betweenprovider.close()
andprovider.connection()
.I'm not sure if this is something y-websocket could/should try and handle itself, but I wanted to file an issue so anyone else using the library and investigating reports of iDevice data loss could hopefully see and workaround the problem since Apple are taking their time to address the root cause.