demio-browser-viewer v7.1.2
Demio Viewer Application
Technologies
- Node (Express)
- React
- jQuery
- Sass
We create the JavaScript bundle with Webpack 4.
Browsers supported
Mobile
- Chrome (Attendees)
- Safari just to show a link to our native App (Attendees)
Desktop
- IE11 (Attendees)
- Firefox (All)
- Chrome (All)
We plan to add support for:
Mobile
- Safari (Attendees)
- Android default browser (Attendees)
Desktop
- Safari (Attendees)
- Edge (Attendees)
Dependencies
Must be installed:
- Yarn
- pm2
- node-sass
Scripts
yarn
Downloads and installs the dependencies in thepackage.json
yarn start
Starts both client and server in development mode watching changesyarn start:dev
Starts the client (webpack)yarn start:llr
Starts the client (webpack)yarn start:dev:server
Starts the server VIEWER-SERVER (node via PM2)yarn logs
Shows pm2 logs of the server VIEWER-SERVERyarn build
builds client bundles for deploymentyarn eslint
Runs airbnb linter with some customizationsyarn eslint -- --fix
Fix the errors or warnings fixable
Server application
The server.js
file is our server entrypoint. It is listeing on port 3051
. The npm script yarn start:dev:server
creates the app in pm2 and watches for changes to restart the server sutomatically. In development this command should be called once only becuse PM2 will keep that process alive running in background forever.
There is a server for static files mounted in the folder: Public
.
There is file credentials
with the token for authentication in our backend.
Routes
/join/:hash
It is the access to the room. Fetch data from the endpoint/rest/auth/check
in the serverbackendUri
(in config file settings) and pass it embeded to the browser. Shows the error page. Check if the browser is in mobile. Sets a cookie for demio conversion pixel feature./simulated-webinar/:hash
It is the access for the simulated webinar./jump/:hash
It is the access for the like live webinar/like-live/
Several endpoints for the like live webinar/resources/pre-signed-url
Used in resource uploads to AWS./system
System check to detect streaming capabilities./chat
Pop out chat./webinar/status
Gets the webinar status. It is requested every 5 minutes.
Views
index
It is the HTML template, handles the Welcome Demio animation. Containsheader
andfooter
sub templates with all the scripts and style links. Google analitys and Sentry error tracking settings are here.chat-popout
For the chat pop out window.banned
Page to show to users banned in a webinar.error
Error page for any kind of error in the server.- like-live-desactivated Page to show to user with Like Life feature desactivated.
- like-live HTML template for Like Live.
- simulated-webinar HTML template for simulated webinar.
- system-check HTML template for system check.
Front application
Single route application based on React components. jQuery is used in some cases to handle DOM manipulation and event subcriptions (we should avoid it).
Config
The root file config.js
contain the URLs and settings for the app in the environments:
- development
- staging
- release
- production
Public folder
assets
contains the JS bundles creates byWebpack 4
.img
images folder.sfx
audio files for sound efects like in the count down when a session is about to start.
Eslint config
Eslint is passed automatically on each commit. The new code in the repo must pass the Airbnb
rules with some customizations. The config is in a npm package demio-code-rules
. The commit hook is in the package.json
it calls the npm script: eslint
.
To avoid the eslint validation you can use -n
: commit -n
.
To disable the commit hook just delete it from the package.json
:
"pre-commit": [
"eslint"
]
Webpack config
Webpack bundles
We create serveral bundles to use in different pages. We use different entry points from the folder Scripts
:
Entrypoints
- webpack.index.js
- webpack.like-live.js
- webpack.mobile.js
- webpack.popoutchat.js
- webpack.simulated-webinar.js
- wwbpack.syscheck.js
JavaScript
- demio.bundle.js (Main Desktop uglyfied)
- demiom.bundle.js (Mobile uglyfied)
- like_live.bundle.js (Like live uglyfied)
- simulated_webinar.bundle.js (Simulated uglyfied)
- syscheck.bundle.js (System Check uglyfied)
- popoutchat.bundle.js (Pop Out Chat)
CSS
- stylem.css (Mobile styles minified)
- style.css (Desktop styles minified)
Initialization flow
The app connects a web-socket with nodeServerUri
(in config file settings). After the connection the event initialized
is received. The event contains webinar
and user
info. At this point any bidirectinal communication is available with the server. Then the Viewer
component is mounted and other web-socket is connected to tokboxServer
(in config file settings). This connection allows us to create and connect the session OTSESSION
. At this point the streaming is ready and the user can publish audio/video or share the screen.
Web-socket
DemioWebsocket
Handles theuWebsocket
management and export a bunch of methods to emit events to the server or propagate the events received form the server using callbacks.Services
ConnectDemioUI
with thewebsocket
and bind the callbacks to update the DemioUI state. (This should be refactored to use less bindings) The idea behind the services is split the socket manager in smaller units.
HTTP Endpoints
From the client the main HTTP requests are done to nodeServerUri
(config file settings). The list of endpoints used is:
- /api/messages/general
- /api/messages/conversation/user
- /api/messages/conversations
- /api/messages/conversation
- /api/resources
- /api/resources/mode
- /api/resources/stats
- /api/polls
- /api/polls/vote
- /api/users
- /like-live/chat/add
- /like-live/attended
- /like-live/graph/save
- /like-live/completed
We also do a request to tokboxServer
(in config file settings) to get the data to initialize the TokBox session.
The old code uses SuperAgent
direcly but we prefer to use the library ajax
that wraps it:
const response = await ajax({
url: `/api/resources?webinarID=${webinarID}&userID=${userID}`
})
if (response) {
const { actions, handouts, polls } = response.body
this.setState({
resources: actions,
handouts,
polls
})
}
The method by default is get
but supports any method:
const response = await ajax({
url: '/api/messages/mode',
method: 'post',
data: {
userID,
mode,
webinarID
}
})
The jwToken
is not required because it is recovered from sessionStorage
.
Fonts
Fonts are managed in the _fonts
sass file.
Icomoon projects
There are two JSON files to install the Icommoon projects. Because we don't have a premium account to need to save this JSON manually and keep it in the repo.
demio-icons
font-awesome
SASS
style
It's the main entrypoint.style.mobile
Entry point for mobiles._globals
Global styles. (Contains duplicated styles, should be refactored)components
Contains the import of the sass file per each component.mixins
Reusable mixins (Some are old stuff senseless nowadays).keyframes
Animations.pages
Folder with styles per page likesystem-check
orerror-page
Components
Index
It is not a component but it is the main entrypoint.DEMIOUI
It is the main component and receives the data from theuser
&webinar
data from the server. (Should be refactored to clean it up)WebinarConsole
Handles the header, the viewer, the waiting animation, the chat and the backstage. (Should be refactored to clean it up)Viewer
Handles the webcam layout, the screen-sharing, the presentation materials and the waiting screen. Uses aStreamer
component.
BrowserNotSupported
Message for unsupported browsers.WaitingScreen: Presenters list shown when there isn't
anything being sharedBackStage
Contains all the subcomponents to handle the backstage menu.WebinarCountDown
Count down before start a session.IndexMobile
It is not a component but it is the main mobile entrypoint.Simulated Webinar
Contains all components used in the simulated webinar. Components from the regular room are used here.
LikeLiveReplay
Contains all the components used in the LLR. It has duplicated code because doesn't reuse components.more...
Libraries
Polyfills
Contains polyfiles for older browsers (IE 11).localEvents
manage the event communication across components of the app. It is a wrapper of the event emitter inDEMIO
namespace.SessionEvents
uses TokBoxsignal
to manage the event communication across clients in the same session.utils
contains some utils to generate UUID an random strings, also theEventListener
used inlocalEvents
.storageHelper
wrapper oflocalStorage
.securityHelper
manages the AES encryption / descryption of web-socket events.demio
DEMIO
public namespace accesible from the console. Contains utilities. For instance it is used to manage the comunication between the popout chat window and the main window. It also has some UI utilities like dialogs.demio-tokbox
manage the subscription/publishing of streams with TokBox.Constants
contains constants per component used accross the app.more...
TOKBOX (RTC)
We use the package @openTok/client
, please read in the release notes important information.
The library demio-tokbox
is currently wrapping the management of the TokBox streams. We plan to use openTok React. demio-tokbox
is used in the Viewer
to publish or subscribe to streams:
- screen
- cam
- mic
- cam & mic in a single stream
TokBox session is a global variable OTSESSION
accesible from the console.
Mobile (Responsive)
Mobile is detected in the server to just add the mobile JS bundle. There is an specific entrypoint for it. We only support attendees roles in mobile.
LLR (Like Live Replay)
It is separeted application that plays a video a reproduces the session using a history with recorded events. Has a basic chat support.
Simulated Webinars
It is a demo session for admins that also uses videos to fake the session but it has support for mic/cam devices, backstage and full chat support because it reuses the same components as in the original room.
DemioUISimulation
is React component that extends DemioUI
to control the session start.
The class Simulation
is the main controller to start, stop, resume the video, run the timer to run each event/frame in the correct time.
The folder Services/Events
contains the lists of simulated events for actions, messages, precreations, users and videos. Every event have a seconds
prop that is used to trigger the event at the correct time.
The class EventExec
create the list of events and run them in loop. Every event check internally if it is the correct time using the methods in the file time.js
.
The sockets callbacks are called programatically in the file socket.js
but we still use a regular websocket connection with some special socket events for the simulaiton.
4 years ago