This document describes how to setup a development environment for BigBlueButton 2.2 (or later). Once setup, you can modify the client and server components.

    The BigBlueButton client is a single page, responsive web application that is built upon the following components:

    • React.js for rendering the user interface in an efficient manner
    • WebRTC for sending/receiving audio and video

    The BigBlueButton server is built upon

    • Meteor.js in ECMA2015 for communication between client and server.
    • MongoDB for keeping the state of each BigBlueButton client consistent with the BigBlueButton server

    The instructions in this guide are step-by-step so you can edit the source, test your changes, and commit any changes to your fork of BigBlueButton.. If you encounter errors when following these steps, stop and double-check that you have done the step correctly. If you are unable to determine the cause of the error, do the following

    • Use Google to search for the error. There is a wealth of information in bigbluebutton-dev that has been indexed by Google.
    • Redo the same steps on a different BigBlueButton server.
    • Post the issue to bigbluebutton-dev with a description of the problem and the steps to reproduce. Post any relevant logs and error messages to Pastebin link them in your post.

    Architecture Overivew

    When you start up a BigBlueButton session, your browser loads the source code for the client which, when loaded, estabilishes a connection to the BigBlueButton server – specifically to the MongoDB database on the server.

    Client

    The MongoDB database contains information about all meetings on the server and, in turn, each client connected to a meeting.

    Each user’s client is only aware of the their meeting’s state, such the user’s public and private chat messages sent and received.

    The following diagram gives an overview of the architecture of the HTML5 client and its communications with the other components in BigBlueButton.

    HTML5 Overview

    The client uses the SASS precompiler to keep the stylesheets short and readable. SASS is a stylesheet language that is compiled into CSS.

    The responsive UI of the HTML5 client is constructed using media queries. Each SASS expression is tied to some specific range of devices and window sizes.

    All the code for the HTML5 client is inside the bigbluebutton/bigbluebutton-html5 folder in GitHub.

    Server

    MongoDB is initalized by a Meteor application (which application?).

    When the Meteor application starts, it connects to redis via a RedisPubSub channel, then sends a JSON request message get_all_meetings_request to bbb-apps, which triggers the following response:

    {
       "payload": {
         "meetings": [
           {
             "meetingID": "183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1415134791204",
             "meetingName": "Demo Meeting",
             "recorded": false,
             "voiceBridge": "70827",
             "duration": 0
           }
         ]
       },
       "header": {
         "timestamp": 3350491563,
         "name": "get_all_meetings_reply",
         "current_time": 1415312516720,
         "version": "0.0.1"
       }
    }
    

    bbb-apps then parses this message and populates theMeetings stored in MongoDB.

    Next, the application obtains an array of all users, presentations and the chat history for each meeting (from where?). Using this information, the application populations the following collections: Users, Chat, Presentations, Shapes, and Slides.

    We are subscribed to receive event messages on the following Redis channel:

    • “to-html5-redis-channel”
    • “from-akka-apps-*”

    And we publish event messages on:

    • “to-akka-apps-redis-channel”

    Throughout the meeting we keep receiving json messages via Redis about all the events in the meetings on the BigBlueButton server. The handling procedure typically involves updating the particular document[s] in the collection.

    Consistency of state

    We rely heavily on the fact that MongoDB on the server side automatically pushes updates to MiniMongo on the client side. The client side subscribes to the published collections on the server side. During the subscription, the meetingId, userId and authToken of the user logged in the client are required. These 3 identifiers provide enough information for the publishing mechanism to decide what subset of the collections the user logged in the client is authorized to view.

    If a user loses connection while in the meeting, a message appears on the screen informing the user about the disconnection and the reconnection countdown. The client will periodically attempt to reconnect. If the reconnection is successful, the client will reappear with everything up to date.

    Before you begin

    This section makes sure you are ready to setup a BigBlueButton development environment.

    Setup a working BigBlueButton server

    Before you can start developing on BigBlueButton, you need to have a working BigBlueButton server (see install BigBlueButton 2.2). The BigBlueButton server already has the HTML5 client and necessary packages to run the client. By starting with a working server, you can customize just the components you want to change. For debugging, you also have the ability to switch back-and-forth between the default-packaged components and any modifications you make.

    For example, suppose you modify the BigBlueButton client and something isn’t working (such as the client is not fully loading), you can easily switch back to the default-packaged client and check that it’s working correctly (thus ruling out any environment issues that may also be preventing your modified client from loading).

    Developing on Windows

    To develop BigBlueButton from within Windows, use VMWare Player or VirtualBox to create first an Ubuntu 16.04 64-bit virtual machine (VM). The associated documentation for VMWare Player and VirtualBox will guide you on setting up a new 16.04 64-bit VM.

    When setting up the VM, it does not matter to BigBlueButton if you setup Ubuntu 16.04 server or desktop. If you install desktop, you’ll have the option of using a graphical interface to edit files. When running the VM, you will need a host operating system capable of running a 64-bit virtual machine.

    Root Privileges

    Important: Do not run commands as the root user and only use sudo command when indicated by instructions. Instead, run the commands in a user (non-root) account. The documention is written using the account firstuser, but you can use any user account.

    sudo ls
    

    wget

    You’ll need to download some files throughout these instructions using wget. If it’s not installed on your server, you can install the package using the following command

    sudo apt-get install wget
    

    Have a GitHub Account

    The BigBlueButton source is hosted on GitHub. You need a GitHub account. In addition, you need to be very familiar with how git works. Specifically, you need to know how to

    • clone a repository
    • create a branch
    • push changes back to a repository

    If you have not used git before, or if the terms clone, branch, and commit are unfamiliar to you, stop now. These are fundamental concepts to git that you need to become competent with before trying to develop on BigBlueButton. To become competent, a good place to start is this free book and GitHub Help pages.

    Using GitHub makes it easy for you to work on your own copy of the BigBlueButton source, store your updates to the source to your GitHub account, and make it easy for you to contribute to BigBlueButton.

    Subscribe to bigbluebutton-dev

    We recommend you subscribe to the bigbluebutton-dev mailing list to follow updates to the development of BigBlueButton and to collaborate with other developers.

    Overivew of Architecture

    Setup a Development Environment

    First, you need to install the core development tools.

    sudo apt-get install git-core ant openjdk-8-jdk-headless
    

    With the JDK installed, you need to set the JAVA_HOME variable. Edit ~/.profile (here we are using vim to edit the file)

    vi ~/.profile
    

    Add the following line at the end of the file

    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
    

    Reload your profile (this will happen automatically when you next login, but we’ll do it explicitly here to load the new environment variable).

    source ~/.profile
    

    Do a quick test to ensure JAVA_HOME is set.

    $ echo $JAVA_HOME
    /usr/lib/jvm/java-8-openjdk-amd64
    

    In the next step, you need to install a number of tools using sdkman.

    curl -s "https://get.sdkman.io" | bash
    source "$HOME/.sdkman/bin/sdkman-init.sh"
    
    sdk install gradle 5.1.1
    sdk install grails 3.3.9
    sdk install sbt 1.2.6
    sdk install maven 3.3.9
    

    You will need to download some files throughout these instructions using curl. If it is not installed on your server, you can install the package using the following command

    $ sudo apt-get install curl
    

    You will need to install Meteor.js.

    $ curl https://install.meteor.com/ | sh
    

    Got the tools setup? Great, now let’s checkout the source.

    Checking out the Source

    Let’s create a directory to hold the source code.

    mkdir ~/dev
    cd ~/dev
    

    Next, using your GitHub account, do the following

    1. Fork the BigBlueButton repository into your GitHub account.
    2. Clone your repository into your ~/dev folder.

    The work on the HTML5 client is occuring in the master branch.

    $ git clone https://github.com/<YOUR_GITHUB_USERNAME>/bigbluebutton.git
    $ cd bigbluebutton
    

    After cloning, you’ll have the following directory (make sure the bigbluebutton directory is within your dev directory).

    Next, make sure you are on the master branch.

    git fetch origin
    git checkout master
    
    

    Confirm that you are working on the master branch.

    $ git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    nothing to commit, working directory clean
    

    Setup of the development environment

    First, shut down the packaged version of the HTML5 client so you are not running two copies in parallel.

    $ sudo systemctl stop bbb-html5
    

    output from the above command contains errors check again the nginx configuration you just edited.

    Running the HTML5 client

    $ cd ~/dev/bigbluebutton/bigbluebutton-html5
    

    Install the npm dependencies (your output may differ)

    $ meteor npm install
    
    > fibers@3.1.1 install /home/ubuntu/dev/bigbluebutton/bigbluebutton-html5/node_modules/fibers
    > node build.js || nodejs build.js
    
    `linux-x64-57-glibc` exists; testing
    Binary is fine; exiting
    
    > husky@1.3.1 install /home/ubuntu/dev/bigbluebutton/bigbluebutton-html5/node_modules/husky
    > node husky install
    
    husky > setting up git hooks
    husky > done
    
    > node-sass@4.11.0 install /home/ubuntu/dev/bigbluebutton/bigbluebutton-html5/node_modules/node-sass
    > node scripts/install.js
    
    Downloading binary from https://github.com/sass/node-sass/releases/download/v4.11.0/linux-x64-57_binding.node
    Download complete..] - :
    Binary saved to /home/ubuntu/dev/bigbluebutton/bigbluebutton-html5/node_modules/node-sass/vendor/linux-x64-57/binding.node
    Caching binary to /home/ubuntu/.npm/node-sass/4.11.0/linux-x64-57_binding.node
    
    > node-sass@4.11.0 postinstall /home/ubuntu/dev/bigbluebutton/bigbluebutton-html5/node_modules/node-sass
    > node scripts/build.js
    
    Binary found at /home/ubuntu/dev/bigbluebutton/bigbluebutton-html5/node_modules/node-sass/vendor/linux-x64-57/binding.node
    Testing binary
    Binary is fine
    npm WARN bbb-html5-client@ No license field.
    
    added 903 packages from 583 contributors and audited 3951 packages in 17.784s
    found 0 vulnerabilities
    

    In order to run the server side of the HTML5 client you will need to execute the following:

    $ npm start
    

    By default, the client will run in development mode. Loading into production environment can be done by passing the value of NODE_ENV:

    $ NODE_ENV=production npm start
    

    Wait until the process starts and confirm that the configuration is valid by navigating to

    http://<your_ip>/html5client/check
    

    The result should be {"html5clientStatus":"running"}.

    Usage

    There are several ways to join a meeting using the HTML5 client:

    Attempt joining on a device which does not have Flash

    If you visit a link (to a BigBlueButton meeting) on your Android/iOS device you will automatically be using the HTML5 client. The same goes for opening the link with a desktop browser if Flash has been disabled.

    Starting from a demo page

    Make sure you have the demos package installed: sudo apt install bbb-demos. Go to http://<your_ip>/ in the browser. Select “API examples”. Navigate to “HTML5 Client Demo” and use the form. You will enter a meeting titled “Demo Meeting”.

    Pass parameter on joining

    Pass joinViaHtml5=true as a parameter and you will be navigating into the meeting using the HTML5 client.

    Configure the server to prefer HTML5 for some/all users

    You can modify bigbluebutton.properties so that all attendees or all moderators (or everyone) joins via HTML5. For this set attendeesJoinViaHTML5Client or moderatorsJoinViaHTML5Client to true and restart BigBlueButton.

    Serve the client over HTTPS

    Make sure you follow the instructions for configuring SSL on BigBlueButton. Test your server using the Flash client. Make sure the audio works and the slides display properly. The HTML5 client does not require any additional configuration to run over https. If the rest of BigBlueButton is running fine as https, you are set!

    Localization with Transifex

    We use Transifex for crowdsourcing for BigBlueButton Internationalization(i18n). The following steps are not a part of the typical installation and are only required for bringing the language strings in github up to date. There are two ways to pull the translation files; using the transifex.sh script or the transifex client.

    Using transifex.sh

    The transifex.sh script aims to make retrieving translation files on the Transifex servers as simple as possible. In order to use the script, you must provide your Transifex credentials which have the appropriate authorization. The script can be used in the following ways.

    $ ./transifex.sh all
    

    Using the all argument will tell the script to download all available translation files.

    $ ./transifex.sh fr de pt-BR
    

    If you only need a specific set of translations, the script can be run with the required locales as argument.

    Setup & Configure Transifex Client

    This is an alternative method to using the transifex.sh and is essentially the manual process for retrieving translation files from the Transifex servers.

    1. Install Transifex Client

    To installation the Transifex client we use pip, a package management system designed to manage and install Python packages.

    $ sudo apt-get install python-pip
    

    Next we use Pip to install the Transifex client.

    $ sudo pip install transifex-client
    

    The following command is used to upgrade the client to the most current version.

    $ pip install --upgrade transifex-client
    

    2. Transifex Project Initialization

    The tx init command is used to initialize a project. Run from the root directory of the application.

    $ tx init
    Creating .tx folder. . .
    Transifex instance [https://www.transifex.com]:
    

    Press Enter (will be prompted for your Transifex username and password)

    Creating skeleton...
    Creating config file...
    ​Done.
    

    This will create a Transifex project file in the current directory containing the project’s configuration file.

    3. Transifex Client configuration

    .tx/config

    The Transifex client uses a per project configuration file. This is located in .tx/config of your project’s root directory and is generated on running the tx init command. It should be updated with the following configuration:

    [main]
    host = https://www.transifex.com
    
    [bigbluebutton-html5.enjson]
    file_filter = private/locales/<lang>.json
    source_file = private/locales/en_US.json
    source_lang = en_US
    type = KEYVALUEJSON
    

    4. Set a Project Remote

    tx set allows you to configure and edit Transifex project files on your local computer.

    The following command is used to initialize a local project for the remote project specified by the URL.

    $ tx set --auto-remote https://www.transifex.com/projects/p/bigbluebutton-html5/resources/enjson/

    Next we can pull language files located on the Transifex server.

    5. Pull: Download Transifex Translations

    To pull all translation files from the Transifex server, the following command is used.

    $ tx pull -a bigbluebutton-html5.enjson

    In the event that there are a lot of translations, instead of pulling all, we can specify which translations we want to acquire.

    $ tx pull -r bigbluebutton-html5.enjson -l pt_BR

    Alternatively, simply download a ZIP archive of all languages in the project from the Transifex project page and unarchive it in the private/locales/ directory.

    Accessibility

    We developed the BigBlueButton HTML5 client with the goal of having the best accessibility support for a web conferencing system.

    In order to accommodate all of the users who may have one or a combination of impairments, we refer to the Web Content Accessibility Guidelines (WCAG) 2.0. This document outlines the standards expected to be included, where applicable, with all HTML markup on the web.

    When dealing with web accessibility there are a few key factors we must keep in mind while developing

    1. Tab Order
    2. Color Contrast
    3. Focus
    4. Semantics
    5. Testing

    Tab Order

    The goal when implementing the tab order is ensuring the elements in the tab sequence are logical and simple.

    When a user presses the tab key focus should move to the next interactable element. If the user continues to press the tab key, focus should move in a logical order through all the interactable elements on the page. The tab focus should be visually identified, currently the HTML5 client adds a thin border to the field, when tab is pressed focus is seen to visibly move.

    Note: A number of users including the following.

    • Those with visual impairments, who rely on screen readers or screen magnifiers.
    • Those with limited dexterity, who depend on the use of the keyboard to using a mouse.
    • Those who can only utilize a single switch to control a computer.

    will all navigate through a page by using the tab button.

    The order of elements in the DOM determine their place in the tab order, for elements that should receive focus. Elements that don’t natively receive focus can be inserted into the tab order by adding a tabindex=”0” property.

    Caution: When using the tabindex property, positive values should generally be avoided because it places elements outside of the natural tab order, this can present issues for screen reader users who rely on navigating the DOM through a linear manner.

    The following extension gives a visual representation of the tab order of a current web document.

    ChromeLens

    offered by ngzhian

    Contrast Ratio Calculator https://chrome.google.com/webstore/detail/chromelens/idikgljglpfilbhaboonnpnnincjhjkd?hl=en

    Focus

    Color Contrast

    When dealing with color contrast we are talking about finding colors for a scheme that not only implement maximum contrast, but gives the appropriate contrast between the content and its background for those who experience low visual impairments, color deficiencies or the loss of contrast typically accompanied by aging.

    The HTML5 client ensures that all visual designs meet the minimum color-contrast ratio for both normal as well as large text on a background, described by the WCAG 2.0 AA standards. “Contrast (Minimum): Understanding Success Criterion 1.4.3.”

    To make sure that we have met these guidelines, there are numerous tools available online which allow the comparison of foreground and background colors using hex values, to see if they fall within the appropriate contrast ratio.

    Contrast Ratio Calculator http://webaim.org/resources/contrastchecker/

    Currently implemented colors:

    Currently implemented element colors Currently implemented typography colors

    • Blue - primary color - action buttons
    • Red - closing audio, indicators and error alerts
    • Green - audio indicator, success alert, check marks
    • Orange - warning alerts
    • Dark Blue - Headings
    • Grey - base typography color

    Note: The ChromeLense extension also provides the ability to view your browser using different personas of users who may view web content with various different visual impairments. This is particularly useful when deciding on appropriate color schemes to best suit a wider range of users.

    Semantics

    Users with visual disabilities can miss out on visual affordances. We need to make sure the information we are trying to express, is expressed in a way that flexible enough so assistive technology can pick up on it; creating an alternative interface for our users. we refer to this as expressing the semantics of an element.

    The HTML5 client uses the WAI-ARIA (Web Accessibility Initiative – Accessible Rich Internet Applications) to provide access to screen readers. The following list of commonly used aria attributes:

    • aria-role
    • aria-label
    • aria-labelledby
    • aria-describedby
    • aria-hidden
    • aria-live
    • aria-expanded
    • aria-haspopup

    #### Links

    HTML5 ARIA spec - http://www.w3.org/TR/aria-in-html/

    ARIA spec - http://www.w3.org/WAI/PF/aria/

    Roles - http://www.w3.org/TR/wai-aria/roles

    States and Properties - http://www.w3.org/TR/wai-aria/states_and_properties

    Design Patterns - http://www.w3.org/TR/wai-aria-practices/#aria_ex

    Testing

    Testing for accessibility can be a somewhat painful process, if you try to manually find and fix all the issues. While it is good practice to go through a checklist and ensure all elements in the HTML5 client meet their accessibility requirements, this process can be very slow and time consuming. For this reason it is suggested to use an automated accessibility auditor first.

    aXe

    offered by Deque Systems

    aXe https://chrome.google.com/webstore/detail/axe/lhdoppojpmngadmnindnejefpokejbdd

    Accessibility Developer Tools

    offered by Google Accessibility

    Accessibility Developer Tools https://chrome.google.com/webstore/detail/accessibility-developer-t/fpkknkljclfencbdbgkenhalefipecmb

    Both of these extensions provide the ability to scan the DOM and report on any accessibility issues based on levels which can be set, weather AA or AAA standards. For the purposes of the HTML5 client we follow the AA guidelines. Any reported errors also come with a listing of potential fixes.

    Note: Once these extensions are installed to the browser they must be run from inside the console.

    Training

    We recommenbd checking out this free online accessibility course which can provide a very good understanding of the basics of dealing with web accessibility for both developers and designers.

    In the event you do not need to take the course but would still like access to the information as reference, the course is also found in full document form . It is a live document which is updated by the developers over at Google.

    Coding Practices

    When making a new component there is a certain structure to implement and existing components to utilize to make your life easier.

    Buttons

    There is a standard button component we use in the client. It is located inside of /imports/ui/shared/Button.jsx. It should be used for every button.

    Font Size

    Inside of /client/stylesheets there is a stylesheet fontSizing.css.

    It will contain style classes such as extraSmallFont, smallFont, mediumFont, etc. Every piece of html with text to display to the client should be assigned one of these classes. This will allow text to scale responsively and still maintain relative size. You can set the class of an element to one of these classes, and have everything inside the container element inherit the font size rather than assign it to each individual child to save some work.

    Localization

    The HTML5 client supports localizations by using the React-Intl which allows the HTML5 client to have fully localized messages which are uploaded to Transifex for translating. As a result of this we have added the ability within the HTML5 client to switch the language of the application.

    The main language file is en.json. When there is a new field to localize, we update en.json, and then the new field string becomes available for crowdsourced translation on Transifex

    When declaring formatted messages we use defineMessages and injectIntl in place of FormattedMessage.

    Import { injectIntl } from ‘react-intl’;          //pass’s messages as prop to the component
    import { defineMessages } from 'react-intl';      //import so we can group together all messages inside a component.
    
    const intlMessages = defineMessages({             //all messages can be defined in intlMessages
      title: {
    	id: 'app.about.title', 	                        //id corresponds to the id in the locale file
    	description: 'About title label in Settings menu', //gives developers additional context about the element/item
      },
    });
    

    We omit the default message prop because it is the same as the string located in the locale file. By doing this we keep context of what the id’s mean while eliminating duplication. Once the messages are defined we then add the following to use the injectIntl:

    export default injectIntl(ComponentName);
    

    From this point we can use the messages directly as they are passed down as props.

    const { intl } = this.props;     //defined messages get passed as props
    
    <Button
        role="button"
        label={intl.formatMessage(intlMessages.title)}   	  //gets rendered to the screen
        aria-label={intl.formatMessage(intlMessages.title)}    //voiced by screen reader
    />
    

    If the browser is requesting a locale file that does not contain all the translations, all the available strings will be merged with the locale file set as the default. In this case all messages will be displayed but may have a mixture of languages.

    If message id’s are missing from the locale file set as the default, and the browser requests the default or another locale containing a portion of the translated strings; there is potential for the missing id’s to not render a message and in this care default to the id of the message. To ensure this does not occur we make sure that the locale specified as the default always contains 100% of the used messages.

    Server Calls

    To make a call to the server from the client, you should refer to the callServer function in /imports/ui/services/api/index.js.

    Always use this in favor of Meteor.call. The callServer function should operate the same way in that you pass the name of the method to call as a string, and then the arguments just like normal.

    Meteor.call()

    Project Structure

    This section covers the structure for the HTML5 project

    Meteor Structure

    imports/               
      startup/                
        client/               
          index.js                      # import client startup through a single index entity
          routes.js                     # set up all routes in the app
          useraccounts-configuration.js # configure login templates
        server/  
          fixtures.js                   # fill the DB with example data on startup
          index.js                      # import server startup through a single index entity
    
      api/
        lists/                          # a unit of domain logic
          server/  
            publications.js             # all list-related publications
            publications.test.js        # tests for the lists publications
          lists.js                      # definition of the Lists collection
          lists.tests.js                # tests for the behavior of that collection
          methods.js                    # methods related to lists
          methods.tests.js              # tests for those methods
    
      ui/  
        components/                     # all reusable components in the application
                                        # can be split by domain if there are many
        layouts/                        # wrapper components for behavior and visuals
        pages/                          # entry points for rendering used by the router
    
    client/  
      main.js                           # client entry point, import all client code
    
    server/
      main.js                           # server entry point, import all server code
    

    Taken from Meteor Structure

    Inside imports is where we store all units of functionality for the HTML5 client.

    Inside API is where we store the collection data that we use, sort of like a model.

    Inside UI is where we store what would be the view for the models.

    API

    Located under /imports/api

    Each sub-directory here will either be a data collection, or some service we use in the client.

    The name of the subdirectory should be in lower-case representing the name of the Mongo collection, or following typical programming collection it will be PascalCased representing a class name.

    Differing from the Meteor Structure is that for security purposes we want the majority of our functionality in the /server directory, which keeps it from loading on the clients.

    The main export or class for the API component should be in index.js, which allows for easy importing. So to import the Polling collection for example, we can use the following code import Polls from 'imports/api/polls/'.

    Since it is index.js we don’t have to specify that file since it is default.

    Naming files this way can conflict with certain conventions where the file name is named after the main class inside it. To go about this we simply have a default export for the collections, and in the case of a collection we export the new instance.

    Inside the /server directory of every API component we have a named file named publications.js. This is where we put the Meteor publish callback for the collection.

    We now have 2 more sub-directories inside the /server directory– methods and modifiers.

    /methods

    Inside /methods we have one file per method. These methods are where we declare the Meteor.Methods for the collection– which are Meteor server methods that can be invoked from the Meteor client. We have one file per method, and they are named in camelCase. They shouldn’t need an export because of how they are registered in Meteor. They will however have to be imported on the server (at startup) to execute the code.

    /modifiers

    Inside /modifiers we have one file per method. These functions that go in here include the functions that modify the collection/data/class, from the server side. We have one file per method, and they are named in camelCase. There should be one export per file. And these will be imported wherever needed. These are almost all functions that will be called from Redis message listeners.

    eventHandlers.js

    Inside imports/api/<collection>/server/ we have a file called eventHandlers.js. This file will contain all the event handlers for the collection.

    /ui

    Inside /ui we will have sub-directories for

    • components

    • services

    • stylesheets

    /services

    will have /api/index.js. Which is where we will store client-side-wide services and helpers. The functions and data in here will all be exported on the last line of the file in one export statement. This allows someone to just look at the last line of the file and easily see what the file exports.

    /components

    Inside this directory each sub-directory will represent a React Component. The name of the sub-directory is what the name of the component is. They are all lowercase, with dashes (-) between words. The standard file are

    • component.jsx

    • container.jsx

    • service.js

    • styles.scss

    Example

    -> /whiteboard

       -> component.jsx

       -> service.js

       -> container.js

       -> /slide/component.jsx

       -> /cursor/component.jsx

       -> /shape-factory/component.jsx

       -> /shapes

           -> /ellipse/component.jsx

           -> /triangle/component.jsx

           -> … <the rest of the shape components>

    Component

    All components will be React ES6 style classes (not React Classes). A component should only need to have one export and it should be the default export. Refer to the official React documentation on how to structure a component class. The component file will be named component.jsx.

    Container

    createContainer()

    A container is a React ES6 class that will pass data to the component. The container will also be in control of whether or not the component should render. A container should retrieve data from the service and pass it into the container class.

    The container file will be named container.jsx. The file should have only one export and should be the default export. The export should be the result of the createContainer() function.

    Service

    The service file should be named service.js.

    The file can export as many function, objects, or other pieces of data as it needs. The service can interface with other collections as well. There should only be one export statement in the file. The last line of the file should export all the functions and pieces of data in an object. Restrain from wrapping everything inside a function and exporting the function wrapper.

    Styles.scss

    All styles should be written in SASS when possible.

    /private/config

    All configuration files are located in /private/config. The file used depends on how you are running the client. In development mode (see npm start above) the configuration from settings-development.json is picked up. When running the packaged bbb-html5 service or when passing NODE_ENV=production, the file settings-production.json is utilized. If you make any changes to the json configuration you will need to restart the html5 client.

    During Meteor.startup() the configuration file is loaded and can be accessed through the Meteor.settings.public object.

    Client Logger

    To assist with monitoring and debugging, the HTML5 client can send its logs to the BigBlueButton server via the logger function. Here’s an example of its use:

    import logger from '/imports/startup/client/logger'; 
    
    logger.warn('Hi on warn') 
    

    The client logger accepts three targets for the logs: console, server and external.

    Name Default Value Accepted Values Description
    target “console” “console”, “external”, “server” Where the logs will be sent to.
    level “info” “debug”, “info”, “warn”, “error” The lowest log level that will be sent. Any log level higher than this will also be sent to the target.
    url - - The end point where logs will be sent to when the target is set to “external”.
    method - “POST”, “PUT” HTTP method being used when using the target “external”.

    There are default values in the HTML5 configuration file /usr/share/meteor/bundle/programs/server/assets/app/config/settings-production.json (bigbluebutton/bigbluebutton-html5/private/config/settings-development.json if you are running the client from source code

        "clientLog": {
          "server": { "enabled": true, "level": "info" },
          "console": { "enabled": false, "level": "debug" },
          "external": { "enabled": false, "level": "info", "url": "https://<YOUR_DOMAIN>/html5Log", "method": "POST" }
        }
    

    Notice that the external option is disabled by default - you can enable it on your own server after a few configuration changes.

    When setting the output to external, the BigBlueButton client will POST the log events to the URL endpoint provided by url. To create an associated endpoint on the BigBlueButton server for the POST request, create a file /etc/bigbluebutton/nginx/client-log.nginx with the following contents:

    location /html5Log {
    	access_log /var/log/nginx/html5-client.log postdata;
    	echo_read_request_body;
    }
    

    Then create a file in /etc/nginx/conf.d/client-log.conf with the following contents:

    log_format postdata '$remote_addr [$time_iso8601] $request_body';
    

    Next, install the full version of nginx.

    sudo apt-get install nginx-full
    

    You may also need to create the external output file and give it the appropriate permissions and ownership:

    sudo touch /var/log/nginx/html5-client.log
    sudo chown www-data:adm /var/log/nginx/html5-client.log
    sudo chmod 640 /var/log/nginx/html5-client.log
    

    Restart BigBlueButton with sudo bbb-conf --restart and launch the BigBlueButton HTML5 client in a new session. You should the logs appearing in /var/log/nginx/html5-client.log as follows

    99.239.102.0 [2018-09-09T14:59:10+00:00] [{\x22name: .. }]
    

    You can follow the logs on the server with the command

    tail -f html5-client.log | sed -u -e 's/\\x22/"/g' -e 's/\\x5C/ /g'
    

    Here’s a sample log entry

    {  
       "name":"clientLogger",
       "level":30,
       "obj":[  
          {  
             "urls":"stun:stun.freeswitch.org"
          }
       ],
       "levelName":"info",
       "msg":"[audio] iceServers",
       "time":"2018-08-27T19:32:57.389Z",
       "src":"https://demo.bigbluebutton.org/html5client/dfe4ad6bfad11b20d1904e76e71d385262781887.js?meteor_js_resource=true:147:782083",
       "v":1,
       "clientInfo":{  
          "sessionToken":"e7boenucj1pwkbfc",
          "meetingId":"183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1535398242909",
          "requesterUserId":"w_klfavdlkumj8",
          "fullname":"Ios",
          "confname":"Demo Meeting",
          "externUserID":"w_klfavdlkumj8"
       },
       "url":"https://demo.bigbluebutton.org/html5client/users",
       "userAgent":"Mozilla/5.0 (iPad; CPU OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1",
       "count":1
    },
    {  
       "name":"clientLogger",
       "level":30,
       "obj":{  
          "userId":"w_klfavdlkumj8",
          "userName":"Ios",
          "topic":"audio"
       },
       "levelName":"info",
       "msg":"[audio] this browser supports websockets",
       "time":"2018-08-27T19:32:57.393Z",
       "src":"https://demo.bigbluebutton.org/html5client/dfe4ad6bfad11b20d1904e76e71d385262781887.js?meteor_js_resource=true:147:782083",
       "v":1,
       "clientInfo":{  
          "sessionToken":"e7boenucj1pwkbfc",
          "meetingId":"183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1535398242909",
          "requesterUserId":"w_klfavdlkumj8",
          "fullname":"Ios",
          "confname":"Demo Meeting",
          "externUserID":"w_klfavdlkumj8"
       },
       "url":"https://demo.bigbluebutton.org/html5client/users",
       "userAgent":"Mozilla/5.0 (iPad; CPU OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1",
       "count":1
    }