Angular Classroom Workshop Tutorial
Build a local classroom workshop with mediasfu-angular@2.3.1: participants,
polls, whiteboard, and breakout-room controls in the supplied Angular room UI.
The project runs against a local MediaSFU Community Edition server and contains
no hosted MediaSFU credential.
Prerequisites
- Node.js 18 to 20, a local MediaSFU Community Edition server, and two profiles.
- HTTPS or
localhost; set the server origin in the component.
Project files
{"private":true,"scripts":{"start":"ng serve"},"dependencies":{"@angular/animations":"19.2.20","@angular/cdk":"19.2.19","@angular/common":"19.2.20","@angular/compiler":"19.2.20","@angular/core":"19.2.20","@angular/forms":"19.2.20","@angular/platform-browser":"19.2.20","@angular/router":"19.2.20","@fortawesome/angular-fontawesome":"1.0.0","@fortawesome/fontawesome-svg-core":"6.7.2","@fortawesome/free-brands-svg-icons":"6.7.2","@fortawesome/free-solid-svg-icons":"6.7.2","@mediapipe/selfie_segmentation":"0.1.1675465747","@zxing/ngx-scanner":"19.0.0","bootstrap":"5.3.8","mediasoup-client":"3.20.0","mediasfu-angular":"2.3.1","ngx-cookie-service":"19.1.2","rxjs":"7.8.0","socket.io-client":"4.8.3","tslib":"2.8.1","zone.js":"0.15.1"},"devDependencies":{"@angular-devkit/build-angular":"19.2.14","@angular/cli":"19.2.14","typescript":"5.5.4"}}
{"version":1,"projects":{"classroom":{"projectType":"application","root":"","sourceRoot":"src","architect":{"build":{"builder":"@angular-devkit/build-angular:application","options":{"browser":"src/main.ts","polyfills":["zone.js"],"tsConfig":"tsconfig.app.json","index":"src/index.html","assets":[],"styles":[]}},"serve":{"builder":"@angular-devkit/build-angular:dev-server","configurations":{"development":{"buildTarget":"classroom:build"}},"defaultConfiguration":"development"}}}}}
{"compilerOptions":{"strict":true,"target":"ES2022","module":"ES2022","moduleResolution":"bundler","lib":["DOM","ES2022"],"skipLibCheck":true},"include":["src/**/*.ts"]}
import { bootstrapApplication } from '@angular/platform-browser';
import { ClassroomWorkshopComponent } from './classroom-workshop.component';
bootstrapApplication(ClassroomWorkshopComponent).catch((error: unknown) => console.error(error));
import { Component } from '@angular/core';
import { MediasfuGeneric } from 'mediasfu-angular';
@Component({selector:'app-root',standalone:true,imports:[MediasfuGeneric],template:`
<main><h1>Classroom workshop</h1><p>Create a conference as teacher, then use Polls, Whiteboard, and Breakout Rooms.</p>
<app-mediasfu-generic [localLink]="communityServerUrl" [connectMediaSFU]="true" [returnUI]="true" /></main>`})
export class ClassroomWorkshopComponent { readonly communityServerUrl = 'http://localhost:3000'; }
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Classroom workshop</title></head><body><app-root></app-root></body></html>
Run
npm install
npm start
Expected result
Create a conference as teacher, then join as learner from a second profile. Create and close a poll, open the whiteboard, and move a learner to and back from a breakout room when those controls are enabled by the local room policy.
Recovery
Keep learners in the main room if a breakout move fails. Close or reopen a poll deliberately after reconnecting, and tell users whether a whiteboard draft was retained by your local room policy.
Cleanup
Return learners from breakouts, close the poll and whiteboard, then have each person use Leave. A local leave is not a room-wide end action.
Release boundary
This is the supported local-server route. For hosted or distributed rooms, the authenticated backend owns room creation and access policy. Never put a Cloud API key in Angular. The supplied Cloud pre-join flow currently checks browser credentials before a callback, so use an approved backend room destination or a server-issued handoff instead of bypassing that check.