Description
Crystal's HTTP::WebSocket
is still lacking in some key parts, which I will go over individually:
- No overview section or basic usage examples
- Incorrect/misleading method naming
- Lack of explicit control
I believe that the first point is fairly self-explanatory: there is very little information about the usage of websockets in the documentation – not even an overview section! This is obviously not helpful for people that are new to websockets or their usage in Crystal. In particular, Crystal's websocket implementation does not have an on_open
method that is common in other websocket libraries in other languages. This is due to the fact that the websocket connection is opened in instantiation (the new
method), so you can simply send to websocket afterwards; nowhere is this distinction made. This could be rectified by adding a simple overview section with examples for websockets, even if it is minimal.
My second point is targeted at the run
method which states:
Continuously receives messages and calls previously set callbacks until the websocket is closed.
While it does say it receives messages and calls the packet callbacks (binary, message, etc), it's quite obvious how one—like a newcomer to Crystal—can misinterpret this. Had this not been stated, the name alone implies that it runs the websocket, which is not the case. The name should reflect its actual purpose which is to listen
for incoming packets and handle them accordingly. The run
method could be deprecated and use the new method under the hood until this change is phased out. The docs should also warn that the method is blocking/fiber-demanding, which is not immediately obvious until you try to execute code after ws.run
(related: #11413).
My third point is mostly extracted from #8435 with additional implementation details, but to summarise: there is no way to manually manage a websocket connection as the run
method automatically handles incoming packets and responses for pings/pongs. There should be an explicit receive
method to receive an incoming packet, and an on_packet
callback handler which users can use to handle incoming packets regardless of whether the user is managing the websocket manually. Ideally, the run
(or listen
I should say) method would use receive
under the hood to prevent code duplication, and in general the code should not have to change too much to accommodate for these features (they're also non-breaking which is always a plus).
WDYT?