|
| 1 | +# How to use Excaliroom |
| 2 | + |
| 3 | +This directory contains guidance for using and integrating the `Excaliroom` server with your existing project. |
| 4 | + |
| 5 | +## Table of contents |
| 6 | + |
| 7 | +- [Getting started](#getting-started) |
| 8 | + - [Pre-requisites](#pre-requisites) |
| 9 | + - [How Excaliroom works](#how-excaliroom-works) |
| 10 | +- [API reference](#api-reference) |
| 11 | +- [Examples](#examples) |
| 12 | +- [FAQ](#faq) |
| 13 | + |
| 14 | +## Getting started |
| 15 | + |
| 16 | +### Pre-requisites |
| 17 | + |
| 18 | +First of all, it is implied that you have `Backend` and `Frontend` applications: |
| 19 | +- `Backend`: It may contain some of your business logic, and it may be written in any programming language. |
| 20 | +- `Frontend`: It is your JavaScript application that will communicate with the `Excaliroom` server. |
| 21 | + |
| 22 | +The `Excaliroom` WebSocket server is only responsible for handling real-time communication between your clients on the same board. |
| 23 | +It does not store any data (except for the current state of the board and connected clients) and does not have any business logic. |
| 24 | + |
| 25 | +However, `Excaliroom` server requires a `JWT` token to authenticate and authorize users. |
| 26 | +The `JWT` token should be: |
| 27 | +- Validated by your `Backend` application. |
| 28 | +- Provided by your `Frontend` application. |
| 29 | + |
| 30 | +The `Excaliroom` server also requires a URL to validate user access to the board. |
| 31 | + |
| 32 | +The neccessary URLs for `JWT` validation and board validation should be provided in the `Excaliroom` server configuration file. |
| 33 | +See the [Configuration](../README.md#configuration) section for more information. |
| 34 | + |
| 35 | +### How Excaliroom works |
| 36 | + |
| 37 | +The `Excaliroom` server uses WebSockets to communicate between clients and broadcast the changes to all connected clients. |
| 38 | +It is a real-time collaboration server that allows multiple users to draw on the same board. |
| 39 | + |
| 40 | +Currently, the sharing mechanism is simple: |
| 41 | +- When a first user connects to the `Excaliroom`, it sends the current state of the board to the WebSocket server. This happens only if the user is the first one to connect to the board. After receiving the board state, the `Excaliroom` creates a new room and stores the board state and the user in the room. |
| 42 | +- With the next user connecting to the same board, the `Excaliroom` adds the user to the existing room and broadcasts the current room state to all connected users. |
| 43 | +- By default, no one can modify the board state. `Excaliroom` can handle board updates only from the _**Leader**_ of the room. By default, after creating a new room, no one is the _**Leader**_ of the room. The _**Leader**_ is the user who can modify the board state. The _**Leader**_ can be dropped by the _**Leader**_ itself. If the _**Leader**_ leaves the room, the _**Leader**_ role is reset so anyone can become the _**Leader**_. |
| 44 | +- When the _**Leader**_ sends a new board state to the `Excaliroom`, the server broadcasts the new board state to all connected users. In other words, the _**Leader**_ is the only user who can modify the board state, while all other users can only view the board state. |
| 45 | +- When the last user leaves the room, the room is deleted from the `Excaliroom`. |
| 46 | + |
| 47 | +The `Excaliroom` sends and receives messages in JSON format. The message format is described in the [API reference](#api-reference) section. |
| 48 | + |
| 49 | +## API reference |
| 50 | + |
| 51 | +Each JSON message contains `event` field that describes the type of the message. The `event` field can have the following values: |
| 52 | +- `connect`: The message is sent by `Frontend` when the user requests to connect to the board. |
| 53 | +- `userConnected`: The message is sent by `Excaliroom` to all connected users when a new user connects to the board. |
| 54 | +- `userDisconnected`: The message is sent by `Excaliroom` to all connected users when a user disconnects from the board. |
| 55 | +- `setLeader`: The message is sent by `Frontend` when the user requests to become the _**Leader**_ of the room and sent by `Excaliroom` to all connected users when the _**Leader**_ changes. |
| 56 | +- `newData`: The message is sent by `Frontend` when the user sends new board data to the server and sent by `Excaliroom` to all connected users when the _**Leader**_ sends new board data. |
| 57 | + |
| 58 | +The JSON message format is as follows: |
| 59 | +1. `connect` event: |
| 60 | +```json |
| 61 | +{ |
| 62 | + "event": "connect", |
| 63 | + "board_id": "<BOARD_ID>", |
| 64 | + "jwt": "<JWT_TOKEN>" |
| 65 | +} |
| 66 | +``` |
| 67 | +- `board_id`: The unique identifier of the board. |
| 68 | +- `jwt`: The JWT token that is used to authenticate and authorize the user. The `Excaliroom` server will use `jwt_validation_url` to validate the JWT token on your `Backend` and `jwt_header_name` to set the JWT to the header. After validating the JWT token, the `Excaliroom` server will use `board_validation_url` to validate the access to the board. See the [Configuration](../README.md#jwt-and-board-urls) section for more information. |
| 69 | + |
| 70 | +2. `userConnected` event: |
| 71 | +```json |
| 72 | +{ |
| 73 | + "event": "userConnected", |
| 74 | + "user_ids": ["<USER_ID_1>", "<USER_ID_2>", ...], |
| 75 | + "leader_id": "<LEADER_ID>" |
| 76 | +} |
| 77 | +``` |
| 78 | +- `user_ids`: The list of user identifiers that are connected to the board. |
| 79 | +- `leader_id`: The identifier of the _**Leader**_ of the room. If the _**Leader**_ is not set, the `leader_id` will be `0`. |
| 80 | + |
| 81 | +3. `userDisconnected` event: |
| 82 | +```json |
| 83 | +{ |
| 84 | + "event": "userDisconnected", |
| 85 | + "user_ids": ["<USER_ID_1>", "<USER_ID_2>", ...], |
| 86 | + "leader_id": "<LEADER_ID>" |
| 87 | +} |
| 88 | +``` |
| 89 | +- `user_ids`: The list of user identifiers that are connected to the board. |
| 90 | +- `leader_id`: The identifier of the _**Leader**_ of the room. If the _**Leader**_ is not set, the `leader_id` will be `0`. |
| 91 | + |
| 92 | +4. `setLeader` event (request): |
| 93 | +```json |
| 94 | +{ |
| 95 | + "event": "setLeader", |
| 96 | + "board_id": "<BOARD_ID>", |
| 97 | + "jwt": "<JWT_TOKEN>" |
| 98 | +} |
| 99 | +``` |
| 100 | +- `board_id`: The unique identifier of the board. |
| 101 | +- `jwt`: The JWT token that is used to authenticate and authorize the user. The `Excaliroom` server will use `jwt_validation_url` to validate the JWT token on your `Backend` and `jwt_header_name` to set the JWT to the header. After validating the JWT token, the `Excaliroom` server will use `board_validation_url` to validate the access to the board. See the [Configuration](../README.md#jwt-and-board-urls) section for more information. |
| 102 | + |
| 103 | +5. `setLeader` event (response): |
| 104 | +```json |
| 105 | +{ |
| 106 | + "event": "setLeader", |
| 107 | + "board_id": "<BOARD_ID>", |
| 108 | + "user_id": "<USER_ID>" |
| 109 | +} |
| 110 | +``` |
| 111 | +- `board_id`: The unique identifier of the board. |
| 112 | +- `user_id`: The identifier of the _**Leader**_ of the room. |
| 113 | + |
| 114 | +6. `newData` event (request): |
| 115 | +```json |
| 116 | +{ |
| 117 | + "event": "newData", |
| 118 | + "board_id": "<BOARD_ID>", |
| 119 | + "jwt": "<JWT_TOKEN>", |
| 120 | + "data": { |
| 121 | + "elements": "EXCALIDRAW_ELEMENTS_JSON", |
| 122 | + "appState": "EXCALIDRAW_APP_STATE_JSON" |
| 123 | + } |
| 124 | +} |
| 125 | +``` |
| 126 | +- `board_id`: The unique identifier of the board. |
| 127 | +- `jwt`: The JWT token that is used to authenticate and authorize the user. The `Excaliroom` server will use `jwt_validation_url` to validate the JWT token on your `Backend` and `jwt_header_name` to set the JWT to the header. After validating the JWT token, the `Excaliroom` server will use `board_validation_url` to validate the access to the board. See the [Configuration](../README.md#jwt-and-board-urls) section for more information. |
| 128 | +- `data`: The board data that is sent by the _**Leader**_ of the room. |
| 129 | + - `elements`: The JSON string of the Excalidraw `elements`. |
| 130 | + - `appState`: The JSON string of the Excalidraw `appState`. |
| 131 | + |
| 132 | +See the [Excalidraw Docs](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/initialdata) documentation for more information. |
| 133 | + |
| 134 | +7. `newData` event (response): |
| 135 | +```json |
| 136 | +{ |
| 137 | + "event": "newData", |
| 138 | + "board_id": "<BOARD_ID>", |
| 139 | + "data": { |
| 140 | + "elements": "EXCALIDRAW_ELEMENTS_JSON", |
| 141 | + "appState": "EXCALIDRAW_APP_STATE_JSON" |
| 142 | + } |
| 143 | +} |
| 144 | +``` |
| 145 | +- `board_id`: The unique identifier of the board. |
| 146 | +- `data`: The board data that is sent by the _**Leader**_ of the room. |
| 147 | + - `elements`: The JSON string of the Excalidraw `elements`. |
| 148 | + - `appState`: The JSON string of the Excalidraw `appState`. |
| 149 | + |
| 150 | +See the [Excalidraw Docs](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/initialdata) documentation for more information. |
| 151 | + |
| 152 | +## Examples |
| 153 | + |
| 154 | +_Later_ |
| 155 | + |
| 156 | +## FAQ |
| 157 | + |
| 158 | +_Later_ |
| 159 | + |
0 commit comments