I'm writing an online whiteboard application for fun, where multiple users view the same whiteboard and can draw on it. I'm using websockets (vanilla JS on the frontend, Scala on the backend), and right now am essentially just broadcasting mouse events from one user to the rest of the users, and rendering the image client-side.
However, this results in a transient shared state, whereas I would like to have users be able to hop on at any time and see the preserved shared state. I'm thinking this will probably require having shared rendering code on the backend and the frontend, so that clients render events as they stream but the server can send raw image data when clients associate.
So my question here is: what are some other design patterns I should be aware of for this kind of project? This is a for fun/learning project, so this is an open-ended question, but I'll accept an answer that contains some useful references for this kind of data flow.