When trying to use websockets the connection hangs on trying to connect
See original GitHub issueI was attempting to use WebSockets and whenever using itty-durable the connection hangs on trying to connect. Below is a small little code sample of what I am using to test the WebSockets. When I use it outside the scope of itty-durable (just on a normal route) it works fine.
import { ThrowableRouter } from 'itty-router-extras'
import { createIttyDurable, withDurables } from 'itty-durable'
export class TestWebsocket extends createIttyDurable({ persistOnChange: false }) {
constructor(state, env) {
super(state, env)
}
websocket() {
const [client, websocket] = Object.values(new WebSocketPair())
websocket.accept()
websocket.send(JSON.stringify({ connected: true }))
websocket.addEventListener('message', ({ data }) => {
websocket.send(JSON.stringify({ data }))
})
return new Response(null, { status: 101, webSocket: client })
}
}
const router = ThrowableRouter()
router.all('*', withDurables())
// Doesnt work
router.get('/ws', ({ TestWebsocket }) => TestWebsocket.get('test').websocket())
// Works
router.get('/ws2', () => {
const [client, websocket] = Object.values(new WebSocketPair())
websocket.accept()
websocket.send(JSON.stringify({ connected: true }))
websocket.addEventListener('message', ({ data }) => {
websocket.send(JSON.stringify({ data }))
})
return new Response(null, { status: 101, webSocket: client })
})
export default {
fetch: router.handle
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (2 by maintainers)
Top Results From Across the Web
Using new Websocket(<uri>) causes the websocket to hang ...
The client cycles through the connections to make and tries each one in order. If it fails or succeeds, it goes to the...
Read more >Websockets are stuck in CONNECTING state. #2098 - GitHub
I'm trying to connect to a local websocket server. socket = new WebSocket("ws://localhost:30003"); The socket never connects properly.
Read more >Troubleshooting connection issues | Socket.IO
You are trying to reach a plain WebSocket server; The server is not reachable; The client is not compatible with the version of...
Read more >IT23126: WEBSOCKETS CLIENT CAN HANG WAITING FOR ...
When upgrading and using a WebSockets connection through DataPower to a back-end server, the client can sometimes hang.
Read more >Websockets service crashes after unexpected closing ... - MSDN
Websockets service crashes (only websockets) if client disconnects without normal closing connection (just close application).
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Would also like to contribute to make this happen, and before doing any work I’d like to summarize what (I think?) the challenges might be:
Upgrade: websocket
header needs to be sent to the DO when making a proxy’d function fetch. In doing this, maybe it makes sense to forward all headers of the current request over to the DO? This is assuming users ofitty-durable
will write something likeDurableObject.connect({ connectionData })
, whereconnect
is a user defined DO method that returns a Response with awebSocket
property.DurableObject.connect({ connectionData })
, currently, is only ever aPOST
request. But, from what I can tell, WebSocket connections MUST be initiated with aGET
request. It’s weird because on Miniflare (--local
) aPOST
request works just fine, so long as I’ve got the header. On “non-local” dev mode with wrangler, using aPOST
request with this setup just crashes wrangler completely. This line inkj
might have to do with it? Not sure, maybe I’m just not doing it right. Either way, it seems like it’d be good to use aGET
request since that’s standard practice.Going about implementing all this, forwarding all request headers through with the proxy’d function fetch request doesn’t seem too difficult IF that’s a sensible solution. Maybe forwarding all headers is a bad idea? I’m not sure.
With the
POST
vsGET
issue, it seems like the proxy’d function fetches withPOST
are pretty ingrained in the system, so breaking out of that for WebSockets could be less pretty. Perhaps theproxyDurable
function’sget
handler could detect theUpgrade: websocket
header, and thus perform aGET
request instead of aPOST
? This wouldn’t support a request body though, which could instead be turned into URL params and be picked up by theitty-durable
DO internal router.Dug into this a bit and it would appear that there’s a header issue or maybe just a response issue where the
webSocket: client
isn’t being forwarded when responding. This is either before the pass back or actually in the pass in where theheaders.Upgrade: 'websocket'
isn’t being passed to the method call into the DO.