It appears that org.glassfish.tyrus.container.grizzly.server.GrizzlyServerContainer uses org.glassfish.grizzly.http.server.HttpServer to listen for the initial HTTP UPGRADE request that starts a WebSocket connection.
The problem is that HttpServer.configureListener() adds an IdleTimeoutFilter to the Grizzly FilterChain. This causes the connection to die after (by default) 30 seconds without activity, even after it is no longer really an HTTP connection.
This behavior goes away if you add a line that removes the IdleTimeoutFilter from the listener's FilterChain in the "start" method in GrizzlyServerContainer.java.
I've also tried calling IdleTimeoutFilter.setCustomTimeout in GrizzlyServerFilter.handleHandshake under "case SUCCESS:" to set the timeout duration for the current connection to IdleTimeoutFilter.FOREVER. This seems to work as well.
(No exact patches as I don't have access to a printer right now to send in a signed OCA)