Skip to content

Add http backend#202

Merged
almarklein merged 24 commits into
mainfrom
http
Jun 29, 2026
Merged

Add http backend#202
almarklein merged 24 commits into
mainfrom
http

Conversation

@almarklein

@almarklein almarklein commented Mar 26, 2026

Copy link
Copy Markdown
Member

A backend that runs a webserver that you can connect to with your browser. Multiple clients are supported (eventually).

Using ASGI, so it can run on any ASGI server and we don't have any hard dependencies 🚀

  • ASGI server.
  • Websocket connection.
  • Implement JS to be a AFM (anywidget front-end module) host. Or JS to control the renderview directly.
  • Python backend module.
  • Support for multiple simultaneous clients.
  • Support for including this in a larger web app, e.g. FastAPI.
  • Allow customizing the html and e.g. add a logo.
  • docs
  • Cleanup

WIP AFM host code, saving here for reference, but I think I'll skip the afm:

        import {default as afm_factory} from './renderview-afm.js'
        const afm = afm_factory();

        // Open websocket
        const ws = new WebSocket("ws://" + location.host + "/ws");

        ws.onopen = (e) => {


        };
        ws.onerror = (e) =?
        ws.onmessage = (e) => {
            let msg = e.data
            if msg.
        }
        ws.onclose = (e) => {
        }

        const callbacks = {}
        const store = {"css_height"}
        let storeChanges = {}

        class AfmModel {
            on (eventName, callback) {
                callbacks[eventName] |= []
                callbacks[eventName].push(callback)
            }
            get (key) {
                return store[key]
            }
            set (key, value ) {
                store[key] = value
                storeChanges[key] = value
            }
            save_changes () {
                ws.send({'type': 'storeChanges', 'data': storeChanges})
                storeChanges = {}
            }
            send (ob) {
                ws.send(ob)
            }
        }

        const model = AfmModel();
        const el = document.getElementById('canvas')

        afm.initialize({model});
        afm.render({el})

@almarklein

almarklein commented Apr 9, 2026

Copy link
Copy Markdown
Member Author

Progress! You can basically replace one line to say from rendercanvas.http import RenderCanvas, loop, and run the same code, but now its a webserver 🚀

image

@almarklein

Copy link
Copy Markdown
Member Author

This is nearly done. Need some cleanup, and resolving some small todos. The server can take multiple clients, who each see the same rendered image. The stream is currently throttled by the slowest connection. Only one client is active: it determines the size of the canvas, and the controls the mouse etc.

Comment thread rendercanvas/core/renderview.js
@almarklein almarklein marked this pull request as ready for review June 24, 2026 13:01
@almarklein

Copy link
Copy Markdown
Member Author

A review would be great. Otherwise I'll just merge this in a few days.

Comment thread rendercanvas/core/renderview.js Outdated
Comment thread rendercanvas/http.py Outdated
Comment thread examples/cube_http.py Outdated

@Vipitis Vipitis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no webdev experience, so I can't give any input on the core changes.

Managed to try it even with multiple clients. I am not sure what the timeout is, but if the active client tabs away it basically freezes the rendering - but it remains the active client.

Should there be some notice about the bidirectional nature by default? Because you might receive events from untrusted clients that could somehow be malicious (I am not sure how this would be exploited beyond a denial of service, by like requesting really large resolutions for example? or maybe a close event? - people will find a way).

finally an idea: what might be possible when running multiple backends at the same time? For example one "presenter" doing it locally while others observe via http (or like a frame server that encodes a video file to save/stream it)

almarklein and others added 2 commits June 29, 2026 11:50
Co-authored-by: Jan <Vipitis@users.noreply.github.com>
Comment thread rendercanvas/core/renderview.js
@almarklein

almarklein commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

but if the active client tabs away it basically freezes the rendering - but it remains the active client.

Right, if the active client tabs away, the browser automatically scales down the animation loop, thereby slowing the animation. And since the active client determines the pace, the other clients get 1 fps or so too. I will add a note in the docs.

Should there be some notice about the bidirectional nature by default? Because you might receive events from untrusted clients that could somehow be malicious

Authorization is the responsibility of the user. In practice, each user will have been authenticated, or connect via a magic link.

That said, making another client the active one once the active client drops may not be acceptable behavior in many use-cases. I consider this a first experimental version; we'll have to flesh out details like that if/when this gets used in real-world scenarios. I will add some notes about this too.

what might be possible when running multiple backends at the same time? For example one "presenter" doing it locally while others observe via http

Although it sounds like an interesting use-case, I suspect that most ppl would simply open a Google Meet 😅

I recon you're also thinking of #102, as in having a primary canvas and then a secondary to stream / watch along.

@almarklein almarklein merged commit f1ab62a into main Jun 29, 2026
21 checks passed
@almarklein almarklein deleted the http branch June 29, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants