htmx
htmx copied to clipboard
Add `reconnect()` to socketWrapper public interface
I'm developing an application using AWS lambda triggered by WebSockets over the API Gateway. After the lambda's maximum execution time is reached (maximum 15 minutes!), the AWS infrastructure will cleanly close the websocket. If we want to re-establish the connection, we need to resort to the following hack:
document.addEventListener('htmx:wsClose', e => {
setTimeout(() => e.detail.elt['htmx-internal-data'].webSocket.init());
});
By adding reconnect() to the socketWrapper public interface, we can rewrite the above to the much nicer:
document.addEventListener('htmx:wsClose', e => {
setTimeout(() => e.detail.socketWrapper.reconnect());
});
I've tested this manually in my setup described above, verifying:
- [x] The htmx:wsClose event is triggered (event is
CloseEvent {isTrusted: true, wasClean: true, code: 1001, reason: 'Going away', type: 'close'...}) - [x] The call to
e.detail.elt['htmx-internal-data'].webSocket.init()reopens the socket - [x] Sending data from inside a ws-send form uses the freshly opened socket
The following trivial patch should implement this feature:
diff --git a/src/ext/ws.js b/src/ext/ws.js
index 05be1eca..dca1b5fc 100644
--- a/src/ext/ws.js
+++ b/src/ext/ws.js
@@ -292,6 +292,7 @@ This extension adds support for WebSockets to htmx. See /www/extensions/ws.md f
wrapper.init();
wrapper.publicInterface = {
+ reconnect: wrapper.init.bind(wrapper),
send: wrapper.send.bind(wrapper),
sendImmediately: wrapper.sendImmediately.bind(wrapper),
queue: wrapper.messageQueue
See also: #381
Presuming you're using JavaScript in the lambda, you might consider cloudflare workers which don't have a time limit and only charge you for actual compute time. Plus CF workers are just faster, cheaper, and run from 300+ edge locations.
I'm sure they do disconnect sometimes, so would benefit from your contribution here, but considerably more rarely.
Anyway, just food for thought.
Presuming you're using JavaScript in the lambda
I'm using PHP with a "keep it running" approach, which enables me to serve requests for up to 15 minutes with only the occasional ~100ms startup time "bump" in request timing. Yes, longer runtime would be great, the alternatives inside AWS are quite a bit more complex AFAIS.
Thanks for the hint though, good to know for other projects! 🙂
Cool, just figured I'd share the info.
Though, while it's probably not practical for you, cf workers support various languages through wasm and others can be transpiled too.
https://developers.cloudflare.com/workers/reference/languages/
Good luck!
I've also experienced frustrations with servers timing out WS connections after not receiving a message within a certain time. Adding a scheduled heartbeat only goes so far, since the browser tab will sleep after being hidden for a while. So having an explicit reconnect function as part of the socket wrapper's public interface would be great, in my opinion.
Has this feature already been approved? If so, I'll submit a PR.
Has this feature already been approved?
Not to my knowledge, neither do I know how I would get it approved. I thought opening an issue here might be enough 🙂