Conversation
403af4d to
9222073
Compare
9222073 to
0202ce2
Compare
There was a problem hiding this comment.
Fab work! Really cool stuff.
I think we're going to need a more flexible API for the websocket service. Currently a message of some kind comes in from the websocket client and then the server decides to either reply or not. This will work for many cases, but other times we need to be able to send a message to the client without the client sending anything. For example, notifying the user of a website when they have recieved a new direct message from another user.
To implement this I think we would want to model the service as an actor that accepts messages. This is an issue as I intend to make some large breaking changes in the OTP/Erlang libraries after finishing with this iteration of LSP work, and I want that to have as small an impact on other libraries such as this one.
On the other hand, this is fantastically useful! Even if we cannot today solve all the possible websocket use cases that doesn't mean we don't want this. If we don't have any good ideas I'd suggest we publish this as a second package, and perhaps later merge them together.
I've also got some very minor stylistic comments around naming but that can be discussed later :)
What are your thoughts?
|
@lpil Thanks for the feedback! So disclaimer, I'm still pretty unfamiliar with I would expect that would be the place that one one hook in to register their new Then that connection tracker can send normal messages to the pid which will trigger the Does that all make sense? Or am I'm misunderstanding how |
|
You've got the general idea, and that is largely how cowboy websockets work today as I understand. It becomes more complex when you consider the types of messages send to the websocket service process. If there's a The API would likely need to look less like a |
|
@lpil Ah, yes totally get it now when it comes to types. I think what I'll do is publish this as a separate experimental package for now then just so I can start playing around with real time apps with Gleam myself. Then once those new OTP APIs exist we can create a better more official API for this package! |
|
FYI, got tests all working over in the new repository here: https://github.com/vstreame/gleam_cowboy_websockets |
|
Thinking about this more, perhaps it's OK that the typing is not amazing here. If that's a limitation of cowboy it's good motivation to make a Gleam websocket server that is well typed and hopefully even faster than cowboy! |
|
@lpil I've also spent the last week learning more about |
(Note: This PR is rebased on #12 just to have some test infra in place. We'll need to merge that before this one can land)(Note 2: Cannot get tests to pass until we get a new version of
nerfout that works with HTTP 3.0 APIs. PR: lpil/nerf#3)What
This is an experimental PR to add Websocket support to the Gleam API. The main change is that when dealing with websockets we more than one "handler". Not only do we need the initial HTTP handler, but we also needs handlers for
As well as we need a piece of state to share between all of these handlers.
Please view the tests for the proposed API.
Why
This would unlock Gleam as a language to build "real-time" applications with. Which would be a very neat use-case!
How
This PR is mostly to discuss the proposed API, but here is also how it currently implements that API (which I'm less sure of). Instead of passing a single handler function to
init/1we instead pass down a map with known keys.handler- The function that is passed ahttp/request.{Request}and returns aWSResponse. AWSResponseis either a wrapper over a normalhttp/response.{Response}or it's anUpgrade(init_state). WhenUpgradeis returned this is signal to us that the developer wants to upgrade the request to a persistant websocket connection.on_ws_init- This handler is used to grab any relevantpids and/or return a frame immediately to the clienton_ws_frame- Handler called whenever a new WS frame is sent from the clienton_message- Handler called whenever pid receives as message from ErlangEach handler is expected to tell us if we want to send any Frames in response as well as what the new state should be updated to.
Links