InDieTasten / zola-codespaces

Implementing support for GitHub Codespaces for zola static site generator
MIT License
1 stars 0 forks source link

Adapt live_reload websocket to work on the same port as the http endpoint for `zola serve` #3

Open InDieTasten opened 6 months ago

Keats commented 6 months ago

Does that work?

InDieTasten commented 6 months ago

Usually, that's how websockets are handled. It's an http request that gets it's protocol elevated / changed into a websocket. At least that's my understanding. I haven't done a lot more research, but it would explain why almost all other live reload tooling doesn't require multiple ports to function properly.

Edit: Just did some more reading. My understanding is this: All new connections are handled by a single connection handler that binds the port for the process. These connections are first handled using http. A header can be used to initiate a protocol change. From that point forward, the connection must be handled by the ws implementation. The websocket protocol was designed specifically to work on the same port as http.

For this task, the current code for serving both http and ws need to be looked at.

Keats commented 6 months ago

That would be a good change if it works, might need to change the ws library if it's not compatible with the http server though

InDieTasten commented 6 months ago

I think the cleanest way to achieve this would be to utilize an addon crate for the hyper server called hyper_tungstenite, which basically adds websocket handling capabilities to hyper (the http server that's currently used for serving) and to adapt the server side live_reload code to work with tungstenite.

Are you cool with that @Keats ?

Keats commented 6 months ago

Yeah that's probably fine

InDieTasten commented 6 months ago

FYI: I'm still in for doing this. I just haven't found time the last week. I'll try to complete this during the weekend

InDieTasten commented 6 months ago

Status update: I've spent a couple hours on this and it's been a bit of a rabbit hole due to updating hyper from version 0 to 1. Code is slowly starting to be compilable again, but I'm not quite there yet. Still have to redo handling of broadcasting updates via websocket as well. Basic setup of the listener and upgrading http to websockets looks good however.

I also believe the code will be quite a bit clearer after this, as all the separate ws port stuff can go, only one port binding is being setup and the handler implementations will be more straight forward using match (method, path) expressions.

It's definitely gonna take a bunch more time, even though it's not a lot of code that's changing, because I'm just a complete noob in Rust, Hyper, Tungstenite and Tokio, so I'm learning as I go.

jplatte commented 5 months ago

You might be interested in the very bare-bones dev-server I recently added to my own SSG, using hyper 1.0 and tower-http's ServeDir: https://github.com/jplatte/hinoki/blob/d413c3a10e13f9b22179d95b95e6318907d0394c/components/dev_server/src/lib.rs#L115

Maybe some of the building blocks there are going to be useful to you, it's quite low on boilerplate but I know it can take a while to figure out how things fit together so maybe the example helps. And while the overall codebase is AGPL, I hereby open up the file linked above for use under the MIT license as well, so you can freely copy any bits that you find useful.

InDieTasten commented 3 months ago

I'm currently pretty busy and have not been able to progress on this. I do want to share my progress on updating the crates, so I pushed my WIP here: https://github.com/InDieTasten/zola-codespaces/tree/3-adapt-live_reload-websocket-to-work-on-the-same-port-as-the-http-endpoint-for-zola-serve

@Keats