Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(doc): add waiting queue documentation #14775

Merged
merged 9 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions resources/cloud-api.swagger
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,29 @@ paths:
type: array
items:
$ref: "#/definitions/PhoneNumberListAnswer"
/waiting-queue/golive:
post:
tags:
- waitingQueueGoLive
summary: Post a go live request
description: Mark the conference as live, notify all visitors waiting.
operationId: goLive
consumes:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Go Live Request"
required: true
schema:
"$ref": "#/definitions/GoLiveRequest"
responses:
'200':
description: Successful operation
'404':
description: Missing conference
'500':
description: Failed operation
securityDefinitions:
token:
type: "apiKey"
Expand Down Expand Up @@ -143,6 +166,12 @@ definitions:
- {"countryCode":"US","tollFree":false,"formattedNumber":"+1 123-456-7890"}
- {"countryCode":"UK","tollFree":true,"formattedNumber":"+44 123 456 7890"}

GoLiveRequest:
type: object
properties:
conference:
type: string
externalDocs:
description: "Find out more about the Jitsi Cloud API"
url: "https://jitsi.org/CloudAPI"

Empty file.
45 changes: 45 additions & 0 deletions resources/waiting-queue/examples/visitor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Conference WebSocket</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="./main.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@stomp/stompjs@7.0.0/bundles/stomp.umd.min.js"></script>
<script src="./visitor.js"></script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div id="main-content" class="container">
<div class="row">
<div class="col-md-6">
<form class="form-inline">
<div class="form-group">
<label for="connect">WebSocket connection:</label>
<button id="connect" class="btn btn-default" type="submit">Connect</button>
<label for="conference">What is your conference?</label>
<input type="text" id="conference" class="form-control" placeholder="Your conference here...">
<button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect
</button>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="conference" class="table table-striped">
<thead>
<tr>
<th>Messages</th>
</tr>
</thead>
<tbody id="messages">
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
63 changes: 63 additions & 0 deletions resources/waiting-queue/examples/visitor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const token = 'JWT_TOKEN_GOES_HERE'

const stompClient = new StompJs.Client({
brokerURL: 'ws://localhost:8060/waiting-queue/visitor/websocket',
});

stompClient.onWebSocketError = (error) => {
console.error('Error with websocket', error);
};

stompClient.onStompError = (frame) => {
console.error('Broker reported error: ' + frame.headers['message']);
console.error('Additional details: ' + frame.body);
};

function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#messages").html("");
}

function connect(conference) {
console.log("Connecting to conference " + conference);

headers = {
Authorization: 'Bearer ' + token
};

stompClient.connectHeaders = headers;

stompClient.onConnect = (frame) => {
setConnected(true);
console.log('Connected: ' + frame);

stompClient.subscribe('/secured/conference/visitor/topic.' + conference, (message) => {
showMessage(message.body);
}, headers);
};

stompClient.activate();
}

function disconnect() {
stompClient.deactivate();
setConnected(false);
console.log("Disconnected");
}

function showMessage(message) {
$("#messages").append("<tr><td>" + message + "</td></tr>");
}

$(function () {
$("form").on('submit', (e) => e.preventDefault());
$( "#connect" ).click(() => connect($("#conference").val()));
$( "#disconnect" ).click(() => disconnect());
});
Binary file added resources/waiting-queue/img/waiting-queue-ds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions resources/waiting-queue/waiting-queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Waiting queue

Visitors queue service is used for managing the visitors queue for the 8x8 video meetings by keeping visitors websocket connections opened and when a moderator opens the meeting, the visitors are notified and allowed to join the meeting.
The moderators should be able to see the visitors count.

## Authentication
ltorje-8x8 marked this conversation as resolved.
Show resolved Hide resolved

The JWT token is sent at least in the CONNECT STOMP message as connect header - see sample code:

```
headers = {
Authorization: 'Bearer ' + token
};

stompClient.connectHeaders = headers;

stompClient.onConnect = (frame) => {
setConnected(true);
console.log('Connected: ' + frame);

stompClient.subscribe('/secured/conference/visitor/topic.' + conference, (message) => {
showMessage(message.body);
}, headers);
};
```

### Visitors

This endpoint should accept only visitor's jaas tokens for a conference specified as param to the endpoint and the token to be valid for that room. The token for visitors contains:
```
context: {
user: {
role: ‘visitor'
}
}
```
It allows visitors to connect to the /visitors websocket and wait for the start message to be published on /secured/conference/visitor/topic.{conference} topic.

### Moderators

This endpoint should accept only moderator's jaas tokens for a conference specified as param to the endpoint and the token to be valid for that room. The token for moderator contains:
```
context: {
user: {
moderator: true
}
}
```
It allows moderators to connect to the /moderator websocket and wait for the status message to be published on /secured/conference/state/topic.{conference} topic (triggered every 15 seconds).

## Flow

The flow is depicted below:

![Flow](img/waiting-queue-ds.png)

## Topics

The topics used:

![Topics](img/waiting-queue-topics.png)

## API

| Endpoint | Type | Auth | Use |
|----------|:-------------:|------:|------:|
| WS /visitor | WebSocket/STOMP | require client token for conference | Visitors open a websocket and wait to receive a message. Message format is not very important, since we’re starting with a single message – “ready to join”. But keep it extensible. If a conference is already live when a visitor opens the ws, immediately send a notification |
| WS /state | WebSocket/STOMP | require client token for conference | Moderators use it to get the number of visitors waiting. Service sends updates for the number of visitors. To reduce traffic send updates at a minimum period and only if the count changed |
| POST /golive | REST | require a server-to-server token for conference | Our backend calls it anytime the visitorsLive state for a conference changes from “false” to “true”, including when a conference is created with visitorsLive=true |

>
> Note: CONNECT and MESSAGE STOMP frames expect an additional header for Authorization
>

More on [STOMP](https://stomp.github.io/stomp-specification-1.2.html).

## Sample code

There is sample code showing how to handle the visitor case [here](./examples/visitor.js).