Hi Raul!
In 4.9 the StreamController was completely rewritten for WebGL, and it makes use of additional functionality that is supported by GeoEvent/StreamServices as well as adds support for automatic re-connection. We also now do the feature processing in a worker. With this we can leverage the GPU to render many more features on the screen and handle faster updates, as well as allow users to take advantage of the client-side querying/filters/effects that we have available for feature-like layers. Instead of just adding new features to a global graphics array (which was what the old implementation did and wasn't very performant), we now store features in a client-side spatial index/data-store that is required both for tiled WebGL rendering, as well as client-side querying. This probably makes us more likely to break if we are lacking the information that we expect.
Note that also starting from 4.9 we no longer advertise that users can use their own websocket server, as this might have been a bit of an overstatement to begin with, especially as StreamServices continue to evolve and add new capabilities. Basically this requires faking a StreamService, and if any functionality is missing, the StreamLayer may not function properly. This may be what is happening as this implementation does not appear to include support for setting filters over the websocket connection. We now always send a filter message, even if no filter is present, as this has virtually no overhead and allows for a single code-path. This also effectively tests a connection that would otherwise fail when setting a filter later, though we should add some timeout logic here so we can log errors to make this more apparent. Additionally, it seems like there might be some issues with the service metadata, esp. concerning the links to the available websocket connections (e.g. wss was showing up as being available despite only starting up a ws connection).
Instead, we want to enable developers to be able to just pass in their own websocket connection without having to fake an entire StreamService. Nothing is settled at this point, but we are thinking about exposing the ability for users to pass in a MessagePort that they could then use to process and stream in whatever data they would like. I'm curious to get your thoughts on this and see if this would provide an easier way of accomplishing what you have in mind.