Initial commit tutorials

This commit is contained in:
pabloFuente 2017-06-09 11:51:25 +02:00
parent a5b1958351
commit b6b3e4024f
104 changed files with 94329 additions and 0 deletions

View File

@ -0,0 +1,44 @@
{
"project": {
"version": "1.0.0-beta.17",
"name": "openvidu-insecure-angular"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": "assets",
"index": "index.html",
"main": "main.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"prefix": "app",
"mobile": false,
"styles": [
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"addons": [],
"packages": [],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"prefixInterfaces": false
}
}

4
openvidu-insecure-angular/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/node_modules
.project
.vscode
yarn.lock

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,88 @@
# openvidu-insecure-angular
This repository contains a group videoconference sample application implemented using OpenVidu. This application is a SPA page implemented in [Angular 2](http://angular.io) and was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.17.
## Start OpenVidu Development Server
To develop a videoconference application with OpenVidu you first have to start an OpenVidu Development Server, that contains all needed services. OpenVidu Development Server is distributed in a single docker image.
To execute OpenVidu Development Server in your local development computer, you need to have docker software installed. You can [install it on Windows, Mac or Linux](https://docs.docker.com/engine/installation/).
To start OpenVidu Development Server execute the following command (depending on your configuration it is is possible that you need to execute it with 'sudo'):
<pre>
docker run -p 8443:8443 --rm -e KMS_STUN_IP=193.147.51.12 -e KMS_STUN_PORT=3478 openvidu/openvidu-server-kms
</pre>
And then wait to a log trace similar to this:
<pre>
INFO: Started OpenViduServer in 5.372 seconds (JVM running for 6.07)
</pre>
If you have installed Docker Toolbox in Windows or Mac, you need to know the IP address of your docker machine excuting the following command:
<pre>
docker-machine ip default
</pre>
Then, open in your browser and visit URL `https://127.0.0.1:8443` (or if you are using Docker Toolbox in Windows or Mac visit `https://<IP>:8443`). Then, browser will complain about insecure certificate. Please accept the selfsigned certificate as valid.
Now you are ready to execute the sample application.
## Executing sample application
In this repository you have a sample JavaScript application that use OpenVidu Development Server to allow videoconferences between a group of users. Please clone it with the following command (you need git installed in your development machine):
<pre>
git clone https://github.com/OpenVidu/openvidu-sample-basic-ng2
</pre>
Then, install NPM dependencies with:
<pre>
cd openvidu-sample-basic-ng2
npm install
</pre>
If you obtain an error executing this command, be sure you have installed Node 4 or highe together with NPM 3 or higher.
Then, you execute the development Angular 2 server executing
<pre>
ng serve
</pre>
Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
If you are using Docker Toolbox for Windows or Mac, you need to modify the sample application code. You have to change the following line in the file `src/app/app.component.ts`:
<pre>
this.openVidu = new OpenVidu("wss://127.0.0.1:8443/");
</pre>
You have to change `127.0.0.1` with the IP of the OpenVidu Development Server obtained in the previous step.
Then you can go to `http://localhost:4200/` to use the sample application.
As you can see, the user name and session is filled automatically in the form to make easier testing the app.
If you open `http://localhost:4200/` in two tabs, you can simulate two users talking together. You can open as tabs as you want, but you need a very powerful development machine to test 3 or more users.
For now, it is not possible use the sample application from a different computer.
## Troubleshooting
If you click the joing button and nothing happens, check the developer tools log. If you see
<pre>
Chrome: using SDP PlanB
lang.js:234Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
Participant.js:32 New local participant undefined, streams opts: []
jsonrpcclient.js:127 Connecting websocket to URI: wss://127.0.0.1:8443/room
browser.js:38 WebSocket connection to 'wss://127.0.0.1:8443/room' failed: WebSocket opening handshake was canceledws @ browser.js:38WebSocketWithReconnection @ webSocketWithReconnection.js:59JsonRpcClient @ jsonrpcclient.js:125OpenVidu.initJsonRpcClient @ OpenVidu.js:63OpenVidu.connect @ OpenVidu.js:35AppComponent.joinSession @ app.component.ts:46_View_AppComponent1._handle_submit_5_0 @ AppComponent.ngfactory.js:533(anonymous function) @ view.js:403(anonymous function) @ dom_renderer.js:249(anonymous function) @ dom_events.js:26ZoneDelegate.invoke @ zone.js:232onInvoke @ ng_zone_impl.js:43ZoneDelegate.invoke @ zone.js:231Zone.runGuarded @ zone.js:128NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:72NgZone.runGuarded @ ng_zone.js:235outsideHandler @ dom_events.js:26ZoneDelegate.invokeTask @ zone.js:265Zone.runTask @ zone.js:154ZoneTask.invoke @ zone.js:335
</pre>
You have to go to
https://localhost:8443/ or https://127.0.0.1:8443/ and accept the certificate

View File

@ -0,0 +1,14 @@
import { OpenviduNg2ExamplePage } from './app.po';
describe('openvidu-ng2-example App', function() {
let page: OpenviduNg2ExamplePage;
beforeEach(() => {
page = new OpenviduNg2ExamplePage();
});
it('should display message saying app works', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('app works!');
});
});

View File

@ -0,0 +1,11 @@
import { browser, element, by } from 'protractor';
export class OpenviduNg2ExamplePage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
}

View File

@ -0,0 +1,16 @@
{
"compileOnSave": false,
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../dist/out-tsc-e2e",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}

View File

@ -0,0 +1,38 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', 'angular-cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-remap-istanbul'),
require('angular-cli/plugins/karma')
],
files: [
{ pattern: './src/test.ts', watched: false }
],
preprocessors: {
'./src/test.ts': ['angular-cli']
},
remapIstanbulReporter: {
reports: {
html: 'coverage',
lcovonly: './coverage/coverage.lcov'
}
},
angularCli: {
config: './angular-cli.json',
environment: 'dev'
},
reporters: ['progress', 'karma-remap-istanbul'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};

View File

@ -0,0 +1,46 @@
{
"name": "openvidu-insecure-angular",
"version": "0.0.0",
"license": "MIT",
"angular-cli": {},
"scripts": {
"start": "ng serve",
"lint": "tslint \"src/**/*.ts\"",
"test": "ng test",
"pree2e": "webdriver-manager update",
"e2e": "protractor"
},
"private": true,
"dependencies": {
"@angular/common": "^2.4.0",
"@angular/compiler": "^2.4.0",
"@angular/core": "^2.4.0",
"@angular/forms": "^2.4.0",
"@angular/http": "^2.4.0",
"@angular/platform-browser": "^2.4.0",
"@angular/platform-browser-dynamic": "^2.4.0",
"@angular/router": "^3.4.0",
"core-js": "^2.4.1",
"openvidu-browser": "1.0.1",
"zone.js": "^0.7.6"
},
"devDependencies": {
"@types/jasmine": "2.5.38",
"@types/node": "~6.0.60",
"@angular/cli": "1.0.0-rc.1",
"@angular/compiler-cli": "^2.4.0",
"codelyzer": "~2.0.0",
"jasmine-core": "~2.5.2",
"jasmine-spec-reporter": "~3.2.0",
"karma": "~1.4.1",
"karma-chrome-launcher": "~2.0.0",
"karma-cli": "~1.0.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-coverage-istanbul-reporter": "^0.2.0",
"protractor": "~5.1.0",
"ts-node": "~2.0.0",
"tslint": "~4.4.2",
"typescript": "~2.0.0"
}
}

View File

@ -0,0 +1,32 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/docs/referenceConf.js
/*global jasmine */
var SpecReporter = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
useAllAngular2AppRoots: true,
beforeLaunch: function() {
require('ts-node').register({
project: 'e2e'
});
},
onPrepare: function() {
jasmine.getEnv().addReporter(new SpecReporter());
}
};

View File

@ -0,0 +1,24 @@
<div *ngIf="!session">
<h1>Join a video session</h1>
<form (submit)="joinSession()" accept-charset="UTF-8">
<p>
<label>Participant:</label>
<input type="text" name="token" id="token" [(ngModel)]="token" required>
</p>
<p>
<label>Session:</label>
<input type="text" name="sessionId" id="sessionId" [(ngModel)]="sessionId" required>
</p>
<p>
<input type="submit" name="commit" value="Join!">
</p>
</form>
</div>
<div *ngIf="session">
<h2>{{sessionId}}</h2>
<input type="button" (click)="testingAction()" value="Test action">
<input type="button" (click)="leaveSession()" value="Leave session">
<div id="publisher"></div>
<div id="subscriber"></div>
</div>

View File

@ -0,0 +1,110 @@
import { OpenVidu, Session, Subscriber, Publisher, Stream } from 'openvidu-browser';
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
private OV: OpenVidu;
private session: Session;
toggle = false;
subscriber: Subscriber;
publisher: Publisher;
stream: Stream;
// Join form
sessionId: string;
token: string;
constructor() {
this.generateParticipantInfo();
}
private generateParticipantInfo() {
this.sessionId = 'SessionA';
this.token = 'Participant' + Math.floor(Math.random() * 100);
}
joinSession() {
this.sessionId = (<HTMLInputElement>document.getElementById('sessionId')).value;
this.token = (<HTMLInputElement>document.getElementById('token')).value;
this.OV = new OpenVidu('wss://' + location.hostname + ':8443/');
this.session = this.OV.initSession('apikey', this.sessionId);
// 2) Specify the actions when events take place
this.session.on('streamCreated', (event) => {
this.stream = event.stream;
this.subscriber = this.session.subscribe(event.stream, 'subscriber', {
insertMode: 'append',
width: '100%',
height: '100%'
});
this.subscriber.on('videoElementCreated', (e) => {
console.warn('VIDEO ELEMENT HAS BEEN CREATED BY SUBSCRIBER!');
console.warn(e);
});
});
this.session.on('streamDestroyed', (event) => {
console.warn('Stream has been destroyed!');
//event.preventDefault(); // Do not remove the HTML video element
});
// 3) Connect to the session
this.session.connect(this.token, (error) => {
// If the connection is successful, initialize a publisher and publish to the session
if (!error) {
// 4) Get your own camera stream with the desired resolution and publish it, only if the user is supposed to do so
this.publisher = this.OV.initPublisher('publisher', {
insertMode: 'append',
width: '100%',
height: '100%'
});
this.publisher.on('videoElementCreated', (event) => {
console.warn('VIDEO ELEMENT HAS BEEN CREATED BY PUBLISHER!');
console.warn(event);
});
// 5) Publish your stream
this.session.publish(this.publisher);
} else {
console.log('There was an error connecting to the session:', error.code, error.message);
}
});
return false;
}
leaveSession() {
if (this.OV) { this.session.disconnect(); };
this.session = null;
this.OV = null;
this.generateParticipantInfo();
}
testingAction() {
// UNSUBSCRIBE-SUBSCRIBE
/*if (!this.toggle) {
this.session.unsubscribe(this.subscriber);
} else {
this.subscriber = this.session.subscribe(this.stream, 'subscriber');
this.subscriber.on('videoElementCreated', (e) => {
console.warn('VIDEO ELEMENT HAS BEEN CREATED BY SUBSCRIBER!');
console.warn(e);
});
}
this.toggle = !this.toggle;*/
// PUBLISHER.DESTROY
/*this.publisher.destroy();*/
}
}

View File

@ -0,0 +1,21 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { StreamComponent } from "./stream.component";
@NgModule({
declarations: [
AppComponent, StreamComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -0,0 +1,2 @@
export * from './app.component';
export * from './app.module';

View File

@ -0,0 +1,49 @@
import { Component, Input } from '@angular/core';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { Stream } from 'openvidu-browser';
@Component({
selector: 'stream',
styles: [`
.participant {
float: left;
width: 20%;
margin: 10px;
}
.participant video {
width: 100%;
height: auto;
}`],
template: `
<div class='participant'>
<p>{{stream.getId()}}</p>
<video autoplay="true" [src]="videoSrc"></video>
</div>`
})
export class StreamComponent {
@Input()
stream: Stream;
videoSrc: SafeUrl;
constructor(private sanitizer: DomSanitizer) { }
ngOnInit() {
let int = setInterval(() => {
if (this.stream.getWrStream()) {
this.videoSrc = this.sanitizer.bypassSecurityTrustUrl(
URL.createObjectURL(this.stream.getWrStream()));
console.log("Video tag src=" + this.videoSrc);
clearInterval(int);
}
}, 1000);
//this.stream.addEventListener('src-added', () => {
// this.video.src = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(this.stream.getWrStream())).toString();
//});
}
}

View File

@ -0,0 +1,3 @@
export const environment = {
production: true
};

View File

@ -0,0 +1,8 @@
// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `angular-cli.json`.
export const environment = {
production: false
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>OpenviduNg2Example</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>

View File

@ -0,0 +1,12 @@
import './polyfills.ts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppModule } from './app/';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -0,0 +1,19 @@
// This file includes polyfills needed by Angular 2 and is loaded before
// the app. You can add your own extra polyfills to this file.
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';

View File

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

View File

@ -0,0 +1,34 @@
import './polyfills.ts';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
Promise.all([
System.import('@angular/core/testing'),
System.import('@angular/platform-browser-dynamic/testing')
])
// First, initialize the Angular testing environment.
.then(([testing, testingBrowser]) => {
testing.getTestBed().initTestEnvironment(
testingBrowser.BrowserDynamicTestingModule,
testingBrowser.platformBrowserDynamicTesting()
);
})
// Then we find all the tests.
.then(() => require.context('./', true, /\.spec\.ts/))
// And load the modules.
.then(context => context.keys().map(context))
// Finally, start Karma to run the tests.
.then(__karma__.start, __karma__.error);

View File

@ -0,0 +1,17 @@
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
}

View File

@ -0,0 +1,5 @@
// Typings reference file, see links for more information
// https://github.com/typings/typings
// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
declare var System: any;

View File

@ -0,0 +1,112 @@
{
"rulesDirectory": [
"node_modules/codelyzer"
],
"rules": {
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"label-position": true,
"label-undefined": true,
"max-line-length": [
true,
140
],
"member-access": false,
"member-ordering": [
true,
"static-before-instance",
"variables-before-functions"
],
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-inferrable-types": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-unreachable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [
true,
"single"
],
"radix": true,
"semicolon": [
"always"
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
],
"directive-selector-prefix": [true, "app"],
"component-selector-prefix": [true, "app"],
"directive-selector-name": [true, "camelCase"],
"component-selector-name": [true, "kebab-case"],
"directive-selector-type": [true, "attribute"],
"component-selector-type": [true, "element"],
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"no-input-rename": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true
}
}

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,78 @@
# openvidu-insecure-js
This repository contains a group videoconference sample application implemented using OpenVidu. This application is a SPA page implemented in plain JavaScript (without any JavaScript framework).
## Start OpenVidu Development Server
To develop a videoconference application with OpenVidu you first have to start an OpenVidu Development Server, that contains all needed services. OpenVidu Development Server is distributed in a single docker image.
To execute OpenVidu Development Server in your local development computer, you need to have docker software installed. You can [install it on Windows, Mac or Linux](https://docs.docker.com/engine/installation/).
To start OpenVidu Development Server execute the following command (depending on your configuration it is is possible that you need to execute it with 'sudo'):
<pre>
docker run -p 8443:8443 --rm -e KMS_STUN_IP=193.147.51.12 -e KMS_STUN_PORT=3478 openvidu/openvidu-server-kms
</pre>
And then wait to a log trace similar to this:
<pre>
INFO: Started OpenViduServer in 5.372 seconds (JVM running for 6.07)
</pre>
If you have installed Docker Toolbox in Windows or Mac, you need to know the IP address of your docker machine excuting the following command:
<pre>
docker-machine ip default
</pre>
Then, open in your browser and visit URL `https://127.0.0.1:8443` (or if you are using Docker Toolbox in Windows or Mac visit `https://<IP>:8443`). Then, browser will complain about insecure certificate. Please accept the selfsigned certificate as valid.
Now you are ready to execute the sample application.
## Executing sample application
In this repository you have a sample JavaScript application that use OpenVidu Development Server to allow videoconferences between a group of users. Please clone it with the following command (you need git installed in your development machine):
<pre>
git clone https://github.com/OpenVidu/openvidu-sample-basic-plainjs
</pre>
First, you need an http web server installed in your development computer to execute the sample application. If you have node.js installed in your development machine, you can use [http-server] to serve application files.(https://github.com/indexzero/http-server). It can be installed with:
<pre>
npm install http-server -g
</pre>
To execute the sample application, execute the following command in the project:
<pre>
cd openvidu-sample-basic-plainjs
http-server ./web
</pre>
If you are using Docker Toolbox for Windows or Mac, you need to modify the sample application code. You have to change the following line in the file `web/app.js`:
<pre>
openVidu = new OpenVidu("wss://127.0.0.1:8443/");
</pre>
You have to change `127.0.0.1` with the IP of the OpenVidu Development Server obtained in the previous step.
Then you can go to `http://127.0.0.1:8080` to execute the sample application.
As you can see, the user name and session is filled automatically in the form to make easier testing the app.
If you open `http://127.0.0.1:8080` in two tabs, you can simulate two users talking together. You can open as tabs as you want, but you need a very powerful development machine to test 3 or more users.
For now, it is not possible use the sample application from a different computer.
## Sample application code
This application is very simple. It has only 4 files:
* `OpenVidu.js`: OpenVidu client. You don't have to manipulate this file.
* `app.js`: Sample application main JavaScritp file. You can manipulate this file to adapt it to your necesities.
* `index.html`: HTML file. It contains the HTML code for the form to connect to a videoconference and for the videoconference itself. You can manipulate this file to adapt it to your necesities.
* `style.css`: Some CSS classes to style HTML. You can manipulate this file to adapt it to your necesities.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,118 @@
var OV;
var session;
/* APPLICATION SPECIFIC METHODS */
window.addEventListener('load', function () {
generateParticipantInfo();
});
window.onbeforeunload = function () {
session.disconnect()
};
function generateParticipantInfo() {
document.getElementById("sessionId").value = "SessionA";
document.getElementById("participantId").value = "Participant" + Math.floor(Math.random() * 100);
}
function appendUserData(videoElement, connection) {
var clientDataJSON = JSON.parse(connection.data);
var dataNode = document.createElement('p');
dataNode.className = "data-node";
dataNode.id = "data-" + connection.connectionId;
dataNode.innerHTML = "Nickname: " + clientDataJSON.clientData;
videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling);
}
function removeUserData(connection) {
var dataNode = document.getElementById("data-" + connection.connectionId);
dataNode.parentNode.removeChild(dataNode);
}
function removeAllUserData() {
var nicknameElements = document.getElementsByClassName('data-node');
while (nicknameElements[0]) {
nicknameElements[0].parentNode.removeChild(nicknameElements[0]);
}
}
/* APPLICATION SPECIFIC METHODS */
/* OPENVIDU METHODS */
function joinSession() {
var sessionId = document.getElementById("sessionId").value;
var token = document.getElementById("participantId").value;
// 1) Get an OpenVidu object and init a session with a sessionId
OV = new OpenVidu("wss://" + location.hostname + ":8443/");
session = OV.initSession("apikey", sessionId);
// 2) Specify the actions when events take place
session.on('streamCreated', function (event) {
// Subscribe to the stream to receive it
var subscriber = session.subscribe(event.stream, 'subscriber');
subscriber.on('videoElementCreated', function (event) {
// Add a new HTML element for the user's nickname
appendUserData(event.element, subscriber.stream.connection);
});
});
session.on('streamDestroyed', function (event) {
// Delete the HTML element with the user's nickname
removeUserData(event.stream.connection);
});
// 3) Connect to the session
session.connect(token, '{"clientData": "' + token + '"}', function (error) {
// If the connection is successful, initialize a publisher and publish to the session
if (!error) {
// 4) Get your own camera stream with the desired resolution and publish it, if the user is supposed to do so
var publisher = OV.initPublisher('publisher', {
audio: true,
video: true,
quality: 'MEDIUM'
});
// 5) Publish your stream
session.publish(publisher);
} else {
console.log('There was an error connecting to the session:', error.code, error.message);
}
});
document.getElementById('session-header').innerText = sessionId;
document.getElementById('join').style.display = 'none';
document.getElementById('session').style.display = 'block';
return false;
}
function leaveSession() {
// 6) Leave the session by calling 'disconnect' method over the Session object
session.disconnect();
// Removing all HTML elements with the user's nicknames
removeAllUserData();
document.getElementById('join').style.display = 'block';
document.getElementById('session').style.display = 'none';
}
/* OPENVIDU METHODS */

View File

@ -0,0 +1,39 @@
<html>
<head>
<title>OpenVidu Sample</title>
<meta charset="utf-8">
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
<script src="OpenVidu.js"></script>
<script src="app.js"></script>
</head>
<body>
<div id="join">
<h1>Join a video session</h1>
<form onsubmit="return joinSession()" accept-charset="UTF-8">
<p>
<label>Participant:</label>
<input type="text" id="participantId" required>
</p>
<p>
<label>Session:</label>
<input type="text" id="sessionId" required>
</p>
<p>
<input type="submit" name="commit" value="Join!">
</p>
</form>
</div>
<div id="session" style="display: none;">
<h2 id="session-header"></h2>
<input type="button" id="buttonLeaveSession" onmouseup="leaveSession()" value="Leave session">
<div id="publisher"></div>
<div id="subscriber"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
#publisher {
float: left;
width: 20%;
margin: 10px;
}
#subscriber {
float: left;
width: 20%;
margin: 10px;
}
video {
width: 100%;
height: auto;
}

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/pablo/Documents/Git/openvidu/openvidu-java-client/target/openvidu-java-client-0.0.1-SNAPSHOT.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

24
openvidu-js-java/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
target/

35
openvidu-js-java/.project Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>openvidu-js-java</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="cloudfoundry.standalone.app" version="1.0"/>
</faceted-project>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[3.8.4.201703310634-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
<config>java:io.openvidu.js.java.App</config>
</configs>
<autoconfigs>
</autoconfigs>
<configSets>
</configSets>
</beansProjectDescription>

201
openvidu-js-java/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1 @@
# openvidu-js-java

102
openvidu-js-java/pom.xml Normal file
View File

@ -0,0 +1,102 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.openvidu</groupId>
<artifactId>openvidu-js-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>openvidu-js-java</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<start-class>io.openvidu.sample.secure.spa.java.App</start-class>
<docker.image.prefix>openvidu</docker.image.prefix>
</properties>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.6.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.2.3</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.war</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>io.openvidu</groupId>
<artifactId>openvidu-java-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package io.openvidu.js.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
}

View File

@ -0,0 +1,74 @@
package io.openvidu.js.java;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import io.openvidu.java.client.OpenViduRole;
@RestController
@RequestMapping("/api-login")
public class LoginController {
public class MyUser {
String name;
String pass;
OpenViduRole role;
public MyUser(String name, String pass, OpenViduRole role) {
this.name = name;
this.pass = pass;
this.role = role;
}
}
public static Map<String, MyUser> users = new ConcurrentHashMap<>();
public LoginController() {
users.put("publisher1", new MyUser("publisher1", "pass", OpenViduRole.PUBLISHER));
users.put("publisher2", new MyUser("publisher2", "pass", OpenViduRole.PUBLISHER));
users.put("subscriber", new MyUser("subscriber", "pass", OpenViduRole.SUBSCRIBER));
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<Object> login(@RequestBody String userPass, HttpSession httpSession) throws ParseException {
System.out.println("Logging in | {user, pass}=" + userPass);
JSONObject userPassJson = (JSONObject) new JSONParser().parse(userPass);
String user = (String) userPassJson.get("user");
String pass = (String) userPassJson.get("pass");
if (login(user, pass)) {
System.out.println("'" + user + "' has logged in");
httpSession.setAttribute("loggedUser", user);
return new ResponseEntity<>(HttpStatus.OK);
} else {
httpSession.invalidate();
return new ResponseEntity<>("User/Pass incorrect", HttpStatus.UNAUTHORIZED);
}
}
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ResponseEntity<Object> logout(HttpSession session) {
System.out.println("'" + session.getAttribute("loggedUser") + "' has logged out");
session.invalidate();
return new ResponseEntity<>(HttpStatus.OK);
}
private boolean login(String user, String pass) {
return (users.containsKey(user) && users.get(user).pass.equals(pass));
}
}

View File

@ -0,0 +1,154 @@
package io.openvidu.js.java;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import io.openvidu.java.client.OpenVidu;
import io.openvidu.java.client.Session;
import io.openvidu.java.client.TokenOptions;
import io.openvidu.java.client.OpenViduRole;
@RestController
@RequestMapping("/api-sessions")
public class SessionController {
OpenVidu openVidu;
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
private String OPENVIDU_URL;
private String SECRET;
public SessionController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
this.SECRET = secret;
this.OPENVIDU_URL = openviduUrl;
this.openVidu = new OpenVidu(OPENVIDU_URL, SECRET);
}
@RequestMapping(value = "/get-sessionid-token", method = RequestMethod.POST)
public ResponseEntity<JSONObject> getSessionIdToken(@RequestBody String sessionNameParam, HttpSession httpSession)
throws ParseException {
try {
checkUserLogged(httpSession);
} catch (Exception e) {
return getErrorResponse(e);
}
System.out.println("Getting sessionId and token | {sessionName}=" + sessionNameParam);
JSONObject sessionJSON = (JSONObject) new JSONParser().parse(sessionNameParam);
String sessionName = (String) sessionJSON.get("session");
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
String serverData = "{\"serverData\": \"" + httpSession.getAttribute("loggedUser") + "\"}";
JSONObject responseJson = new JSONObject();
if (this.mapSessions.get(sessionName) != null) {
// Session already exists: return existing sessionId and a new token
System.out.println("Existing session " + sessionName);
try {
String sessionId = this.mapSessions.get(sessionName).getSessionId();
String token = this.mapSessions.get(sessionName)
.generateToken(new TokenOptions.Builder().data(serverData).role(role).build());
this.mapSessionIdsTokens.get(sessionId).put(token, OpenViduRole.PUBLISHER);
responseJson.put(0, sessionId);
responseJson.put(1, token);
return new ResponseEntity<>(responseJson, HttpStatus.OK);
} catch (Exception e) {
return getErrorResponse(e);
}
} else {
// New session: return a new sessionId and token
System.out.println("New session " + sessionName);
try {
Session session = this.openVidu.createSession();
String sessionId = session.getSessionId();
String token = session.generateToken(new TokenOptions.Builder().data(serverData).role(role).build());
this.mapSessions.put(sessionName, session);
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
this.mapSessionIdsTokens.get(sessionId).put(token, OpenViduRole.PUBLISHER);
responseJson.put(0, sessionId);
responseJson.put(1, token);
return new ResponseEntity<>(responseJson, HttpStatus.OK);
} catch (Exception e) {
return getErrorResponse(e);
}
}
}
@RequestMapping(value = "/remove-user", method = RequestMethod.POST)
public ResponseEntity<JSONObject> removeUser(@RequestBody String sessionNameToken, HttpSession httpSession)
throws Exception {
try {
checkUserLogged(httpSession);
} catch (Exception e) {
return getErrorResponse(e);
}
System.out.println("Removing user | {sessionName, token}=" + sessionNameToken);
JSONObject sessionNameTokenJSON = (JSONObject) new JSONParser().parse(sessionNameToken);
String sessionName = (String) sessionNameTokenJSON.get("sessionName");
String token = (String) sessionNameTokenJSON.get("token");
if (this.mapSessions.get(sessionName) != null) {
String sessionId = this.mapSessions.get(sessionName).getSessionId();
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
// User left the session
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
// Last user left the session
this.mapSessions.remove(sessionName);
}
return new ResponseEntity<>(HttpStatus.OK);
} else {
System.out.println("Problems in the app server: the TOKEN wasn't valid");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
} else {
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
} else {
System.out.println("Problems in the app server: the SESSION does not exist");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
private ResponseEntity<JSONObject> getErrorResponse(Exception e) {
JSONObject json = new JSONObject();
json.put("cause", e.getCause());
json.put("error", e.getMessage());
json.put("exception", e.getClass());
return new ResponseEntity<>(json, HttpStatus.INTERNAL_SERVER_ERROR);
}
private void checkUserLogged(HttpSession httpSession) throws Exception {
if (httpSession == null || httpSession.getAttribute("loggedUser") == null) {
throw new Exception("User not logged");
}
}
}

View File

@ -0,0 +1,12 @@
spring.profiles.active=container
server.port: 5000
server.ssl.enabled: true
server.ssl.key-store: classpath:openvidu-selfsigned.jks
server.ssl.key-store-password: openvidu
server.ssl.key-store-type: JKS
server.ssl.key-alias: openvidu-selfsigned
openvidu.url: https://service-openvidu-server-kms:8443/
openvidu.secret: MY_SECRET

View File

@ -0,0 +1,9 @@
server.port: 5000
server.ssl.enabled: true
server.ssl.key-store: classpath:openvidu-selfsigned.jks
server.ssl.key-store-password: openvidu
server.ssl.key-store-type: JKS
server.ssl.key-alias: openvidu-selfsigned
openvidu.url: https://localhost:8443/
openvidu.secret: MY_SECRET

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,205 @@
var OV;
var userName;
var session;
var sessionName;
var sessionId;
var token;
/* APPLICATION BROWSER METHODS */
window.onbeforeunload = function () { // Gracefully leave session
if (session) {
removeUser();
leaveSession();
}
logOut();
}
function appendUserData(videoElement, connection) {
var clientDataJSON = JSON.parse(connection.data.split('%/%')[0]);
var serverDataJSON = JSON.parse(connection.data.split('%/%')[1]);
$("<p id='data-" + connection.connectionId + "' class='data-node'>Nickname: " + clientDataJSON.clientData +
"<br/>Username: " + serverDataJSON.serverData + "</p>"
).insertAfter(videoElement);
}
function removeUserData(connection) {
$("#data-" + connection.connectionId).remove();
}
function removeAllUserData() {
$(".data-node").remove();
}
function isPublisher() {
return userName.includes('publisher');
}
/* APPLICATION BROWSER METHODS */
/* APPLICATION BACKEND METHODS */
function logIn() {
var user = $("#user").val();
userName = user;
var pass = $("#pass").val();
var jsonBody = JSON.stringify({
'user': user,
'pass': pass
});
httpRequest('POST', '/api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
console.warn(userName + ' login');
$("#name-user").text(user);
$("#not-logged").hide();
$("#logged").show();
// Random nickName and session
$("#sessionName").val("Session " + Math.floor(Math.random() * 10));
$("#participantName").val("Participant " + Math.floor(Math.random() * 100));
});
}
function logOut() {
httpRequest('GET', '/api-login/logout', null, 'Logout WRONG', function successCallback(response) {
console.warn(userName + ' logout');
$("#not-logged").show();
$("#logged").hide();
});
}
function getSessionIdAndToken(callback) {
sessionName = $("#sessionName").val();
var jsonBody = JSON.stringify({
'session': sessionName
});
httpRequest('POST', '/api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
sessionId = response[0];
token = response[1];
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
callback();
});
}
function removeUser() {
var jsonBody = JSON.stringify({
'sessionName': sessionName,
'token': token
});
httpRequest('POST', '/api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
console.warn(userName + " correctly removed from session");
});
}
function httpRequest(method, url, body, errorMsg, callback) {
var http = new XMLHttpRequest();
http.open(method, url, true);
http.setRequestHeader('Content-type', 'application/json');
http.addEventListener('readystatechange', processRequest, false);
http.send(body);
function processRequest() {
if (http.readyState == 4) {
if (http.status == 200) {
try {
callback(JSON.parse(http.responseText));
} catch (e) {
callback();
}
} else {
console.warn(errorMsg);
console.warn(http.responseText);
}
}
}
}
/* APPLICATION BACKEND METHODS */
/* OPENVIDU METHODS */
function joinSession() {
getSessionIdAndToken(function () {
// 1) Get an OpenVidu object and init a session with a sessionId
OV = new OpenVidu("wss://" + location.hostname + ":8443/");
session = OV.initSession("apikey", sessionId);
// 2) Specify the actions when events take place
session.on('streamCreated', function (event) {
// Subscribe to the stream to receive it
var subscriber = session.subscribe(event.stream, 'subscriber');
subscriber.on('videoElementCreated', function (event) {
// Add a new HTML element for the user's nickname
appendUserData(event.element, subscriber.stream.connection);
});
});
session.on('streamDestroyed', function (event) {
// Delete the HTML element with the user's nickname
removeUserData(event.stream.connection);
});
// 3) Connect to the session
session.connect(token, '{"clientData": "' + $("#participantName").val() + '"}', function (error) {
// If the connection is successful, initialize a publisher and publish to the session (only if the user is supposed to do so)
if (!error) {
// If the user has enough permissions
if (isPublisher()) {
// 4) Get your own camera stream with the desired resolution and publish it
var publisher = OV.initPublisher('publisher', {
audio: true,
video: true,
quality: 'MEDIUM'
});
// 5) Publish your stream
session.publish(publisher);
} else {
console.warn('You don\'t have permissions to publish');
}
} else {
console.warn('There was an error connecting to the session:', error.code, error.message);
}
});
$('#session-header').text(sessionName);
$('#join').hide();
$('#session').show();
return false;
});
}
function leaveSession() {
// 6) Leave the session by calling 'disconnect' method over the Session object
session.disconnect();
session = null;
// Removing all HTML elements with the user's nicknames
removeAllUserData();
$('#join').show();
$('#session').hide();
}
/* OPENVIDU METHODS */

View File

@ -0,0 +1,82 @@
<html>
<head>
<title>OpenVidu Sample</title>
<meta charset="utf-8">
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
</head>
<body>
<div id="not-logged">
<form onsubmit="return false">
<p>
<label>User</label>
<input type="text" id="user" required>
</p>
<p>
<label>Pass</label>
<input type="password" id="pass" required>
</p>
<p>
<button id="login-btn" onclick="logIn()">Log in</button>
</p>
</form>
<table style="border: 1px solid">
<tr>
<th>User</th>
<th>Pass</th>
</tr>
<tr>
<td>publisher1</td>
<td>pass</td>
</tr>
<tr>
<td>publisher2</td>
<td>pass</td>
</tr>
<tr>
<td>subscriber</td>
<td>pass</td>
</tr>
</table>
<p>PUBLISHER: send and receive media</p><p>SUBSCRIBER: receive media</p>
</div>
<div id="logged" hidden>
<div id="join">
<h1>Hello, <span id="name-user" style="color:red"></span>! Join a video session</h1>
<form onsubmit="return false">
<p>
<label>Name:</label>
<input type="text" id="participantName" required>
</p>
<p>
<label>Session:</label>
<input type="text" id="sessionName" required>
</p>
<p>
<button id="join-btn" onclick="joinSession()">Join!</button>
</p>
</form>
<p>
<button id="logout-btn" onclick="logOut()">Log out</button>
</p>
</div>
<div id="session" style="display: none;">
<h2 id="session-header"></h2>
<input type="button" id="buttonLeaveSession" onmouseup="removeUser(); leaveSession()" value="Leave session">
<div id="publisher"></div>
<div id="subscriber"></div>
</div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="OpenVidu.js"></script>
<script src="app.js"></script>
</html>

View File

@ -0,0 +1,29 @@
#publisher {
float: left;
width: 20%;
margin: 10px;
}
#subscriber {
float: left;
width: 20%;
margin: 10px;
}
video {
width: 100%;
height: auto;
}
table {
border: 0;
}
th {
text-align: left;
}
td {
text-align: left;
padding-right: 15px;
}

View File

@ -0,0 +1,38 @@
package io.openvidu.js.java.test;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

60
openvidu-js-node/.gitignore vendored Normal file
View File

@ -0,0 +1,60 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.vscode/

201
openvidu-js-node/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1 @@
# openvidu-js-node

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDgzCCAmugAwIBAgIJALDBPXTrlAhlMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
BAYTAkVTMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhPcGVuVmlkdTEh
MB8GCSqGSIb3DQEJARYSb3BlbnZpZHVAZ21haWwuY29tMB4XDTE3MDUzMDE1MjQx
N1oXDTI3MDUyODE1MjQxN1owWDELMAkGA1UEBhMCRVMxEzARBgNVBAgMClNvbWUt
U3RhdGUxETAPBgNVBAoMCE9wZW5WaWR1MSEwHwYJKoZIhvcNAQkBFhJvcGVudmlk
dUBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDbK/i
LN80IBnGUbzA4AFl4KQEX6RCreythnfOSnIcQSTP+KjesZMFgsGV0LteDxeCJ+kq
4YoS+CW7ojvOEz3xjCgo4tFdevz8ZoeO0RBQIbARbPako4OXC6vWs6LHwCR0aDWo
9HfS1Uusb8g77csRPRlNA3DGR8dcRTiEBdfHS6Jh/7V7XiDlaxPXj+iIY8PyCqOf
gv4clDt17R+dendDsgYxbmZaodrppNocMQIyUaDIwI4DZOa8nQYk9uuUhkiAFAQB
O642bx6NI0qDu5KgtMmbaS6s+rMnrL8eeZOicqff6XoC6tk6GE8Fo4iYkxp2gAiT
sigaSwpNRWhupISVAgMBAAGjUDBOMB0GA1UdDgQWBBTi3sXqpf42vUNehFU6y4Pn
PTJFRDAfBgNVHSMEGDAWgBTi3sXqpf42vUNehFU6y4PnPTJFRDAMBgNVHRMEBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBfl0C7XAbPdJzCjCsboMTzfC2B4uwspbST
MbUGnmNkTwzeOOsrLQmlCznKGprYV9vGR0MwBzYw2swWCzg/2MLN8swW7NF9gMkK
K61AANxT0qZV/aZhdM7W//pHJoQYsBsQT7cuTrL/VB/niD81uMA/mSWyXIn8KDIy
CPY6jiZ4qiIJnQWhWm1Cazv6O7wjDisvB1cCJhDvBv42KkFwtigt5MQnBEGOI2LD
iKCkXfj33E5B6n0sEel68WgYi6rx2tsR9lzAjCRF+jgNd7FfeUi999m7ykgEACR5
OYRqkVcIXz30r9RxQyFqZLNzyO9oaVZpex8ZbWwEzNXG2ccddnMJ
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAw2yv4izfNCAZxlG8wOABZeCkBF+kQq3srYZ3zkpyHEEkz/io
3rGTBYLBldC7Xg8XgifpKuGKEvglu6I7zhM98YwoKOLRXXr8/GaHjtEQUCGwEWz2
pKODlwur1rOix8AkdGg1qPR30tVLrG/IO+3LET0ZTQNwxkfHXEU4hAXXx0uiYf+1
e14g5WsT14/oiGPD8gqjn4L+HJQ7de0fnXp3Q7IGMW5mWqHa6aTaHDECMlGgyMCO
A2TmvJ0GJPbrlIZIgBQEATuuNm8ejSNKg7uSoLTJm2kurPqzJ6y/HnmTonKn3+l6
AurZOhhPBaOImJMadoAIk7IoGksKTUVobqSElQIDAQABAoIBAGr/2HFjFjbpGJOw
b0O/oqRQUh2e7EYiCoOcK37E3iPAO1KvmG6OFayfwjSwG9bNNpbqGU2EPeBTA/3v
PwV/HZxinB5+yhl/3IKp9LDqoR7uwwNXgNf2O3d5SXX91zO9bXhbEn5WlEDYzl00
uxKtCVF//ZlgN+AoruxDbkVDGbkhKHGzvqOW+BWwbYHPOttQ9TQx2ss5+DekpDFV
/FuvXGOcSSV/N+WbDwsqUiM8ovkcflEgQjZYlAY4Ro2U2buf3fKEmy1jxSznNp30
QA4WyYypyS8Hz6S/F4nsjtS3ufCurrWBv4vt2qB+8tH//07NUacjQWZdvEAtaJ+G
IyJgsOUCgYEA38b2SQiw74fwoK6so2XdpCzOObLQBOT1aeZQjt3v8XZ0MPzwWJZm
VkMBmolcEw24xA3jHhOQYafAGjRdaKxlRbJyGJqwENfAs7hO5JSLLWWXsorJQcb7
1OVTFPt7NZopx2Kw7kGGuj9884w57cSl9lsuMptqk8W7pbTo5opOfl8CgYEA35CR
x23kaFDh8+zKUuSdIrkUJ66cazgOfF0FYKiDewd1sGEdZT+gq7Wo8Hi8cp9q+Kuq
MkGrTzu21yMi2fo7RKoSOtV4RQViu6PuoYR/KvRq4F4abHEAivAG4xhPQife84IB
NkDQXaE9EXTP7DXPwj4HV8CnC9LC2qPFU7GVeYsCgYBWPK6c5qSJKrIouif9sDwC
EOJIighwWmvZK9DPvefB/gw49MEK4qr9g0US8Oxyy07w/wkPhiqV97eoYZW9yPIe
Me6WXMaNNxgkKlr86+HW1NfpDmMQ3kYefWHPLDsHJSoElJvqtYXeMKlOkjOg1a+/
iNP83Lftyr3N1jIK5jHpsQKBgE1+clm7qOnT547C7JrxLdrEZs0ehI/R3YuUPvHz
V6gEvPHHqAXZmVsL3CSG5WOiCNVrw9Ip2zTa0RUf08vVJkg1353PMyJRrJi4SVZp
dB8ym/1sASLHxNVkQC7l1UtsQKcN0Fe6/b8GzgFICW6qdHqzP55WZFD/3JUnIZZS
PyrjAoGBAMfuE0Nrw9Fq7f8+U/SsqiW9djJp4R34EF5n8qHkotfRoAbGktCGxLoF
QMbB9X0ibRMpxEKPHj+V0FXu9zUKFuqoriRc3alQYLNzJEdKeQQ/AN5xjG3ilM6D
/FunImbvSdJLjR9Ue6vlFdOquHevBCFDiHOJPQJ/y4qyZR5Avluw
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,24 @@
{
"name": "openvidu-js-node",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "ng test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/OpenVidu/openvidu-tutorials.git"
},
"author": "openvidu@gmail.com",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/OpenVidu/openvidu-tutorials/issues"
},
"homepage": "https://github.com/OpenVidu/openvidu-tutorials#readme",
"dependencies": {
"body-parser": "^1.17.2",
"express": "^4.15.3",
"express-session": "^1.15.3"
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,204 @@
var OV;
var userName;
var session;
var sessionName;
var sessionId;
var token;
/* APPLICATION BROWSER METHODS */
window.onbeforeunload = function () { // Gracefully leave session
if (session) {
removeUser();
leaveSession();
}
logOut();
}
function appendUserData(videoElement, connection) {
var clientDataJSON = JSON.parse(connection.data.split('%/%')[0]);
var serverDataJSON = JSON.parse(connection.data.split('%/%')[1]);
$("<p id='data-" + connection.connectionId + "' class='data-node'>Nickname: " + clientDataJSON.clientData +
"<br/>Username: " + serverDataJSON.serverData + "</p>"
).insertAfter(videoElement);
}
function removeUserData(connection) {
$("#data-" + connection.connectionId).remove();
}
function removeAllUserData() {
$(".data-node").remove();
}
function isPublisher() {
return userName.includes('publisher');
}
/* APPLICATION BROWSER METHODS */
/* APPLICATION BACKEND METHODS */
function logIn() {
var user = $("#user").val();
userName = user;
var pass = $("#pass").val();
var jsonBody = JSON.stringify({
'user': user,
'pass': pass
});
httpRequest('POST', '/api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
console.warn(userName + ' login');
$("#name-user").text(user);
$("#not-logged").hide();
$("#logged").show();
// Random nickName and session
$("#sessionName").val("Session " + Math.floor(Math.random() * 10));
$("#participantName").val("Participant " + Math.floor(Math.random() * 100));
});
}
function logOut() {
httpRequest('GET', '/api-login/logout', null, 'Logout WRONG', function successCallback(response) {
console.warn(userName + ' logout');
$("#not-logged").show();
$("#logged").hide();
});
}
function getSessionIdAndToken(callback) {
sessionName = $("#sessionName").val();
var jsonBody = JSON.stringify({
'session': sessionName
});
httpRequest('POST', '/api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
sessionId = response[0];
token = response[1];
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
callback();
});
}
function removeUser() {
var jsonBody = JSON.stringify({
'sessionName': sessionName,
'token': token
});
httpRequest('POST', '/api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
console.warn(userName + " correctly removed from session");
});
}
function httpRequest(method, url, body, errorMsg, callback) {
var http = new XMLHttpRequest();
http.open(method, url, true);
http.setRequestHeader('Content-type', 'application/json');
http.addEventListener('readystatechange', processRequest, false);
http.send(body);
function processRequest() {
if (http.readyState == 4) {
if (http.status == 200) {
try {
callback(JSON.parse(http.responseText));
} catch (e) {
callback();
}
} else {
console.warn(errorMsg);
console.warn(http.responseText);
}
}
}
}
/* APPLICATION BACKEND METHODS */
/* OPENVIDU METHODS */
function joinSession() {
getSessionIdAndToken(function () {
// 1) Get an OpenVidu object and init a session with a sessionId
OV = new OpenVidu("wss://" + location.hostname + ":8443/");
session = OV.initSession("apikey", sessionId);
// 2) Specify the actions when events take place
session.on('streamCreated', function (event) {
// Subscribe to the stream to receive it
var subscriber = session.subscribe(event.stream, 'subscriber');
subscriber.on('videoElementCreated', function (event) {
// Add a new HTML element for the user's nickname
appendUserData(event.element, subscriber.stream.connection);
});
});
session.on('streamDestroyed', function (event) {
// Delete the HTML element with the user's nickname
removeUserData(event.stream.connection);
});
// 3) Connect to the session
session.connect(token, '{"clientData": "' + $("#participantName").val() + '"}', function (error) {
// If the connection is successful, initialize a publisher and publish to the session (only if the user is supposed to do so)
if (!error) {
// If the user has enough permissions
if (isPublisher()) {
// 4) Get your own camera stream with the desired resolution and publish it
var publisher = OV.initPublisher('publisher', {
audio: true,
video: true,
quality: 'MEDIUM'
});
// 5) Publish your stream
session.publish(publisher);
} else {
console.warn('You don\'t have permissions to publish');
}
} else {
console.warn('There was an error connecting to the session:', error.code, error.message);
}
});
$('#session-header').text(sessionName);
$('#join').hide();
$('#session').show();
return false;
});
}
function leaveSession() {
// 6) Leave the session by calling 'disconnect' method over the Session object
session.disconnect();
session = null;
// Removing all HTML elements with the user's nicknames
removeAllUserData();
$('#join').show();
$('#session').hide();
}
/* OPENVIDU METHODS */

View File

@ -0,0 +1,82 @@
<html>
<head>
<title>OpenVidu Sample</title>
<meta charset="utf-8">
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
</head>
<body>
<div id="not-logged">
<form onsubmit="return false">
<p>
<label>User</label>
<input type="text" id="user" required>
</p>
<p>
<label>Pass</label>
<input type="password" id="pass" required>
</p>
<p>
<button id="login-btn" onclick="logIn()">Log in</button>
</p>
</form>
<table style="border: 1px solid">
<tr>
<th>User</th>
<th>Pass</th>
</tr>
<tr>
<td>publisher1</td>
<td>pass</td>
</tr>
<tr>
<td>publisher2</td>
<td>pass</td>
</tr>
<tr>
<td>subscriber</td>
<td>pass</td>
</tr>
</table>
<p>PUBLISHER: send and receive media</p><p>SUBSCRIBER: receive media</p>
</div>
<div id="logged" hidden>
<div id="join">
<h1>Hello, <span id="name-user" style="color:red"></span>! Join a video session</h1>
<form onsubmit="return false">
<p>
<label>Name:</label>
<input type="text" id="participantName" required>
</p>
<p>
<label>Session:</label>
<input type="text" id="sessionName" required>
</p>
<p>
<button id="join-btn" onclick="joinSession()">Join!</button>
</p>
</form>
<p>
<button id="logout-btn" onclick="logOut()">Log out</button>
</p>
</div>
<div id="session" style="display: none;">
<h2 id="session-header"></h2>
<input type="button" id="buttonLeaveSession" onmouseup="removeUser(); leaveSession()" value="Leave session">
<div id="publisher"></div>
<div id="subscriber"></div>
</div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="OpenVidu.js"></script>
<script src="app.js"></script>
</html>

View File

@ -0,0 +1,29 @@
#publisher {
float: left;
width: 20%;
margin: 10px;
}
#subscriber {
float: left;
width: 20%;
margin: 10px;
}
video {
width: 100%;
height: auto;
}
table {
border: 0;
}
th {
text-align: left;
}
td {
text-align: left;
padding-right: 15px;
}

246
openvidu-js-node/server.js Normal file
View File

@ -0,0 +1,246 @@
// Check launch arguments
if (process.argv.length != 4) {
console.log("Usage: node " + __filename + " OPENVIDU_URL OPENVIDU_SECRET");
process.exit(-1);
}
// For demo purposes we ignore self-signed certificate
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
// Imports
var express = require('express');
var fs = require('fs');
var session = require('express-session');
var https = require('https');
var bodyParser = require('body-parser'); // pull information from HTML POST (express4)
var app = express(); // create our app w/ express
// Configuration
app.use(session({
saveUninitialized: true,
resave: false,
secret: 'MY_SECRET'
}));
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
app.use(bodyParser.urlencoded({
'extended': 'true'
})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({
type: 'application/vnd.api+json'
})); // parse application/vnd.api+json as json
// listen (start app with node server.js)
var options = {
key: fs.readFileSync('openvidukey.pem'),
cert: fs.readFileSync('openviducert.pem')
};
https.createServer(options, app).listen(5000);
console.log("App listening on port https://[]:5000");
// Environment variables
var OPENVIDU_URL = process.argv[2];
var OPENVIDU_SECRET = process.argv[3];
// Mock database
var users = [{
user: "publisher1",
pass: "pass",
role: "PUBLISHER"
}, {
user: "publisher2",
pass: "pass",
role: "PUBLISHER"
}, {
user: "subscriber",
pass: "pass",
role: "SUBSCRIBER"
}];
// Objects for storing active sessions and users
var mapSessionNameSessionId = {};
var mapSessionIdsTokens = {};
// APIRest
app.post('/api-login/login', function (req, res) {
var user = req.body.user;
var pass = req.body.pass;
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
if (login(user, pass)) {
console.log("'" + user + "' has logged in");
req.session.loggedUser = user;
res.status(200).send();
} else {
console.log("'" + user + "' invalid credentials");
req.session.destroy();
res.status(401).send('User/Pass incorrect');
}
});
app.get('/api-login/logout', function (req, res) {
console.log("'" + req.session.loggedUser + "' has logged out");
req.session.destroy();
res.status(200).send();
});
app.post('/api-sessions/get-sessionid-token', function (req, res) {
if (!isLogged(req.session)) {
req.session.destroy();
res.status(401).send('User not logged');
} else {
var sessionName = req.body.session;
var role = users.find(u => (u.user === req.session.loggedUser)).role;
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
var sessionId = mapSessionNameSessionId[sessionName];
if (sessionId) {
console.log('Existing session ' + sessionName);
getToken(sessionId, role, serverData, function (token) {
mapSessionIdsTokens[sessionId].push(token);
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.status(200).send({
0: sessionId,
1: token
});
});
} else {
console.log('New session ' + sessionName);
getSessionId(function (sessionId) {
mapSessionNameSessionId[sessionName] = sessionId;
mapSessionIdsTokens[sessionId] = [];
getToken(sessionId, role, serverData, function (token) {
mapSessionIdsTokens[sessionId].push(token);
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.status(200).send({
0: sessionId,
1: token
});
});
});
}
}
});
app.post('/api-sessions/remove-user', function (req, res) {
if (!isLogged(req.session)) {
req.session.destroy();
res.status(401).send('User not logged');
} else {
var sessionName = req.body.sessionName;
var token = req.body.token;
console.log('Removing user | {sessionName, token}={' + sessionName + ", " + token + '}');
var sessionId = mapSessionNameSessionId[sessionName];
if (sessionId) {
var tokens = mapSessionIdsTokens[sessionId];
if (tokens) {
var index = tokens.indexOf(token);
if (index !== -1) { // User left the session
tokens.splice(index, 1);
console.log(sessionName + ': ' + mapSessionIdsTokens[sessionId].toString());
} else {
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
console.log(msg);
res.status(500).send(msg);
}
if (mapSessionIdsTokens[sessionId].length == 0) { // Last user left the session
console.log(sessionName + ' empty!');
delete mapSessionNameSessionId[sessionName];
}
res.status(200).send();
} else {
var msg = 'Problems in the app server: the SESSIONID wasn\'t valid';
console.log(msg);
res.status(500).send(msg);
}
} else {
var msg = 'Problems in the app server: the SESSION does not exist';
console.log(msg);
res.status(500).send(msg);
}
}
});
function login(user, pass) {
return (users.find(u => (u.user === user) && (u.pass === pass)));
}
function isLogged(session) {
return (session.loggedUser != null);
}
function getBasicAuth() {
return 'Basic ' + (new Buffer('OPENVIDUAPP:' + OPENVIDU_SECRET).toString('base64'));
}
// HTTP request to OpenVidu Server to get a sessionId
function getSessionId(callback) {
var options = {
hostname: OPENVIDU_URL,
port: 8443,
path: '/api/sessions',
method: 'POST',
headers: {
'Authorization': getBasicAuth()
}
}
const req = https.request(options, (res) => {
var body = '';
res.on('data', (d) => {
// Continuously update stream with data
body += d;
});
res.on('end', function () {
// Data reception is done
var parsed = JSON.parse(body);
callback(parsed.id);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
}
// HTTP request to OpenVidu Server to get a token
function getToken(sessionId, role, data, callback) {
var requestBody = JSON.stringify({
'session': sessionId,
'role': role,
'data': data
});
var options = {
hostname: OPENVIDU_URL,
port: 8443,
path: '/api/tokens',
method: 'POST',
headers: {
'Authorization': getBasicAuth(),
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(requestBody)
}
};
const req = https.request(options, (res) => {
var body = '';
res.on('data', (d) => {
// Continuously update stream with data
body += d;
});
res.on('end', function () {
// Data reception is done
var parsed = JSON.parse(body);
callback(parsed.token);
});
});
req.on('error', (e) => {
console.error(e);
});
req.write(requestBody);
req.end();
}

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/pablo/Documents/Git/openvidu/openvidu-java-client/target/openvidu-java-client-0.0.1-SNAPSHOT.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

24
openvidu-mvc-java/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
target/

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>openvidu-mvc-java</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@ -0,0 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="cloudfoundry.standalone.app" version="1.0"/>
</faceted-project>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[3.8.4.201703310634-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
<config>java:io.openvidu.mvc.java.App</config>
</configs>
<autoconfigs>
</autoconfigs>
<configSets>
</configSets>
</beansProjectDescription>

201
openvidu-mvc-java/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1 @@
# openvidu-mvc-java

56
openvidu-mvc-java/pom.xml Normal file
View File

@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.openvidu</groupId>
<artifactId>openvidu-mvc-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<name>openvidu-mvc-java</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<start-class>io.openvidu.sample.secure.mvc.java.App</start-class>
<docker.image.prefix>openvidu</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.openvidu</groupId>
<artifactId>openvidu-java-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package io.openvidu.mvc.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
}

View File

@ -0,0 +1,88 @@
package io.openvidu.mvc.java;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import io.openvidu.java.client.OpenViduRole;
@Controller
public class LoginController {
public class MyUser {
String name;
String pass;
OpenViduRole role;
public MyUser(String name, String pass, OpenViduRole role) {
this.name = name;
this.pass = pass;
this.role = role;
}
}
public static Map<String, MyUser> users = new ConcurrentHashMap<>();
public LoginController() {
users.put("publisher1", new MyUser("publisher1", "pass", OpenViduRole.PUBLISHER));
users.put("publisher2", new MyUser("publisher2", "pass", OpenViduRole.PUBLISHER));
users.put("subscriber", new MyUser("subscriber", "pass", OpenViduRole.SUBSCRIBER));
}
@RequestMapping(value = "/dashboard", method = { RequestMethod.GET, RequestMethod.POST })
public String login(@RequestParam(name = "user", required = false) String user,
@RequestParam(name = "pass", required = false) String pass, Model model, HttpSession httpSession) {
String userName = (String) httpSession.getAttribute("loggedUser");
if (userName != null) { // User is already logged
model.addAttribute("username", userName);
return "dashboard";
}
System.out.println("Logging in | {user, pass}={" + user + ", " + pass + "}");
if (login(user, pass)) { // User is logging in
System.out.println("'" + user + "' has logged in");
httpSession.setAttribute("loggedUser", user);
model.addAttribute("username", user);
return "dashboard";
} else {
return "index";
}
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public String logout(Model model, HttpSession httpSession) {
if (checkUserLogged(httpSession)) {
model.addAttribute("username", httpSession.getAttribute("loggedUser"));
return "dashboard";
}
httpSession.invalidate();
return "index";
}
@RequestMapping(value = "/", method = RequestMethod.POST)
public String logout(@RequestParam(name = "islogout", required = false) String islogout, HttpSession httpSession) {
if (checkUserLogged(httpSession) && islogout.equals("true")){
System.out.println("'" + httpSession.getAttribute("loggedUser") + "' has logged out");
httpSession.invalidate();
}
return "index";
}
private boolean login(String user, String pass) {
return (user != null &&
pass != null &&
users.containsKey(user) && users.get(user).pass.equals(pass));
}
private boolean checkUserLogged(HttpSession httpSession) {
return !(httpSession == null || httpSession.getAttribute("loggedUser") == null);
}
}

View File

@ -0,0 +1,15 @@
package io.openvidu.mvc.java;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MainController {
@RequestMapping(value = "/")
public String index(Model model) {
return "index";
}
}

View File

@ -0,0 +1,142 @@
package io.openvidu.mvc.java;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import io.openvidu.java.client.OpenVidu;
import io.openvidu.java.client.OpenViduRole;
import io.openvidu.java.client.Session;
import io.openvidu.java.client.TokenOptions;
@Controller
public class SessionController {
OpenVidu openVidu;
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
private String OPENVIDU_URL;
private String SECRET;
public SessionController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
this.SECRET = secret;
this.OPENVIDU_URL = openviduUrl;
this.openVidu = new OpenVidu(OPENVIDU_URL, SECRET);
}
@RequestMapping(value = "/session", method = RequestMethod.POST)
public String joinSession(@RequestParam(name = "data") String clientData,
@RequestParam(name = "session-name") String sessionName, Model model, HttpSession httpSession) {
try {
checkUserLogged(httpSession);
} catch (Exception e) {
return "index";
}
System.out.println("Getting sessionId and token | {sessionName}={" + sessionName + "}");
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
String serverData = "{\"serverData\": \"" + httpSession.getAttribute("loggedUser") + "\"}";
if (this.mapSessions.get(sessionName) != null) {
// Session already exists: return existing sessionId and a new token
System.out.println("Existing session " + sessionName);
try {
String sessionId = this.mapSessions.get(sessionName).getSessionId();
String token = this.mapSessions.get(sessionName)
.generateToken(new TokenOptions.Builder().data(serverData).role(role).build());
this.mapSessionIdsTokens.get(sessionId).put(token, OpenViduRole.PUBLISHER);
model.addAttribute("sessionId", sessionId);
model.addAttribute("token", token);
model.addAttribute("nickName", clientData);
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
model.addAttribute("sessionName", sessionName);
return "session";
} catch (Exception e) {
return "dashboard";
}
} else {
// New session: return a new sessionId and token
System.out.println("New session " + sessionName);
try {
Session session = this.openVidu.createSession();
String sessionId = session.getSessionId();
String token = session.generateToken(new TokenOptions.Builder().data(serverData).role(role).build());
this.mapSessions.put(sessionName, session);
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
this.mapSessionIdsTokens.get(sessionId).put(token, OpenViduRole.PUBLISHER);
model.addAttribute("sessionId", sessionId);
model.addAttribute("token", token);
model.addAttribute("nickName", clientData);
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
model.addAttribute("sessionName", sessionName);
return "session";
} catch (Exception e) {
return "dashboard";
}
}
}
@RequestMapping(value = "/leave-session", method = RequestMethod.POST)
public String removeUser(@RequestParam(name = "session-name") String sessionName,
@RequestParam(name = "token") String token, Model model, HttpSession httpSession) throws Exception {
try {
checkUserLogged(httpSession);
} catch (Exception e) {
return "index";
}
System.out.println("Removing user | sessioName=" + sessionName + ", token=" + token);
if (this.mapSessions.get(sessionName) != null) {
String sessionId = this.mapSessions.get(sessionName).getSessionId();
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
System.out.println(sessionName + ": " + this.mapSessionIdsTokens.get(sessionId).toString());
// User left the session
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
// Last user left the session
this.mapSessions.remove(sessionName);
System.out.println(sessionName + " empty!");
}
model.addAttribute("sessionId", sessionId);
return "leave-session";
} else {
System.out.println("Problems in the app server: the TOKEN wasn't valid");
return "leave-session";
}
} else {
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
return "leave-session";
}
} else {
System.out.println("Problems in the app server: the SESSION does not exist");
return "leave-session";
}
}
private void checkUserLogged(HttpSession httpSession) throws Exception {
if (httpSession == null || httpSession.getAttribute("loggedUser") == null) {
throw new Exception("User not logged");
}
}
}

View File

@ -0,0 +1,9 @@
server.port: 5000
server.ssl.enabled: true
server.ssl.key-store: classpath:openvidu-selfsigned.jks
server.ssl.key-store-password: openvidu
server.ssl.key-store-type: JKS
server.ssl.key-alias: openvidu-selfsigned
openvidu.url: https://localhost:8443/
openvidu.secret: MY_SECRET

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,29 @@
#publisher {
float: left;
width: 20%;
margin: 10px;
}
#subscriber {
float: left;
width: 20%;
margin: 10px;
}
video {
width: 100%;
height: auto;
}
table {
border: 0;
}
th {
text-align: left;
}
td {
text-align: left;
padding-right: 15px;
}

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>OpenVidu Demo Java MVC Secure</title>
<link rel="stylesheet" type="text/css" href="style.css"></link>
</head>
<body>
<h1>
Hello, <span th:text="${username}" style="color: red"></span>! Join a video session
</h1>
<form action="/session" method="post">
<p>
<label>User</label> <input type="text" id="data" name="data" required="true"></input>
</p>
<p>
<label>Session</label> <input type="text" id="session-name" name="session-name" required="true"></input>
</p>
<p>
<button type="submit">Join!</button>
</p>
</form>
<p>
<form action="/" method="post">
<input type="hidden" name="islogout" value="true"></input>
<button type="submit">Log out</button>
</form>
</p>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
window.onload = function () { // Generate participant info
$("#session-name").val("Session " + Math.floor(Math.random() * 10));
$("#data").val("Participant " + Math.floor(Math.random() * 100));
}
</script>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>OpenVidu Demo Java MVC Secure</title>
<link rel="stylesheet" type="text/css" href="style.css"></link>
</head>
<body>
<form action="/dashboard" method="post">
<p>
<label>User</label> <input type="text" name="user" required="true"></input>
</p>
<p>
<label>Pass</label> <input type="password" name="pass" required="true"></input>
</p>
<p>
<button type="submit">Log in</button>
</p>
</form>
<table style="border: 1px solid">
<tr>
<th>User</th>
<th>Pass</th>
</tr>
<tr>
<td>publisher1</td>
<td>pass</td>
</tr>
<tr>
<td>publisher2</td>
<td>pass</td>
</tr>
<tr>
<td>subscriber</td>
<td>pass</td>
</tr>
</table>
<p>PUBLISHER: send and receive media</p>
<p>SUBSCRIBER: receive media</p>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>OpenVidu Demo Java MVC Secure</title>
</head>
<body>Leaving session...
</body>
<script src="OpenVidu.js"></script>
<script>
window.location.href = '/dashboard';
</script>
</html>

View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>OpenVidu Demo Java MVC Secure</title>
<link rel="stylesheet" type="text/css" href="style.css"></link>
</head>
<body>
<h2 th:text="${sessionName}"></h2>
<form action="/leave-session" method="post">
<input type="hidden" name="session-name" th:value="${sessionName}"></input>
<input type="hidden" name="token" th:value="${token}"></input>
<button type="submit" onclick="leaveSession()">Leave session</button>
</form>
<div id="publisher"></div>
<div id="subscriber"></div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="OpenVidu.js"></script>
<script th:inline="javascript">
var sessionId = [[${sessionId}]];
var token = [[${token}]];
var nickName = [[${nickName}]];
var userName = [[${userName}]];
var sessionName = [[${sessionName}]];
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' +
sessionId + ", TOKEN:" + token + ")");
// 1) Get an OpenVidu object an initialize a Session
var OV = new OpenVidu("wss://" + location.hostname + ":8443/");
var session = OV.initSession("apikey", sessionId);
// 2) Specify the actions when events take place
session.on('streamCreated', function (event) {
// Subscribe to the stream to receive it
var subscriber = session.subscribe(event.stream, 'subscriber');
subscriber.on('videoElementCreated', function (event) {
// Add a new HTML element for the user's nickname
appendUserData(event.element, subscriber.stream.connection);
});
});
session.on('streamDestroyed', function (event) {
// Delete the HTML element with the user's nickname
removeUserData(event.stream.connection);
});
// 3) Connect to the session
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
// If the connection is successful
if (!error) {
// If the user has enough permissions
if (isPublisher(userName)) {
// 4) Get your own camera stream with the desired resolution and publish it, only if the user is supposed to do so
var publisher = OV.initPublisher('publisher', {
audio: true,
video: true,
quality: 'MEDIUM'
});
// 5) Publish your stream
session.publish(publisher);
} else {
console.warn('You don\'t have permissions to publish');
}
} else {
console.warn('There was an error connecting to the session:', error.code, error.message);
}
});
function leaveSession() {
session.disconnect();
}
function appendUserData(videoElement, connection) {
var clientDataJSON = JSON.parse(connection.data.split('%/%')[0]);
var serverDataJSON = JSON.parse(connection.data.split('%/%')[1]);
$('<p id="data-' + connection.connectionId + '">Nickname: ' + clientDataJSON.clientData +
'<br/>Username: ' + serverDataJSON.serverData + '</p>'
).insertAfter(videoElement);
}
function removeUserData(connection) {
$("#data-" + connection.connectionId).remove();
}
function isPublisher(userName) {
return userName.includes('publisher');
}
</script>
</html>

View File

@ -0,0 +1,38 @@
package io.openvidu.mvc.java.test;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

60
openvidu-mvc-node/.gitignore vendored Normal file
View File

@ -0,0 +1,60 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.vscode/

201
openvidu-mvc-node/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1 @@
# openvidu-mvc-node

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDgzCCAmugAwIBAgIJALDBPXTrlAhlMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
BAYTAkVTMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhPcGVuVmlkdTEh
MB8GCSqGSIb3DQEJARYSb3BlbnZpZHVAZ21haWwuY29tMB4XDTE3MDUzMDE1MjQx
N1oXDTI3MDUyODE1MjQxN1owWDELMAkGA1UEBhMCRVMxEzARBgNVBAgMClNvbWUt
U3RhdGUxETAPBgNVBAoMCE9wZW5WaWR1MSEwHwYJKoZIhvcNAQkBFhJvcGVudmlk
dUBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDbK/i
LN80IBnGUbzA4AFl4KQEX6RCreythnfOSnIcQSTP+KjesZMFgsGV0LteDxeCJ+kq
4YoS+CW7ojvOEz3xjCgo4tFdevz8ZoeO0RBQIbARbPako4OXC6vWs6LHwCR0aDWo
9HfS1Uusb8g77csRPRlNA3DGR8dcRTiEBdfHS6Jh/7V7XiDlaxPXj+iIY8PyCqOf
gv4clDt17R+dendDsgYxbmZaodrppNocMQIyUaDIwI4DZOa8nQYk9uuUhkiAFAQB
O642bx6NI0qDu5KgtMmbaS6s+rMnrL8eeZOicqff6XoC6tk6GE8Fo4iYkxp2gAiT
sigaSwpNRWhupISVAgMBAAGjUDBOMB0GA1UdDgQWBBTi3sXqpf42vUNehFU6y4Pn
PTJFRDAfBgNVHSMEGDAWgBTi3sXqpf42vUNehFU6y4PnPTJFRDAMBgNVHRMEBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBfl0C7XAbPdJzCjCsboMTzfC2B4uwspbST
MbUGnmNkTwzeOOsrLQmlCznKGprYV9vGR0MwBzYw2swWCzg/2MLN8swW7NF9gMkK
K61AANxT0qZV/aZhdM7W//pHJoQYsBsQT7cuTrL/VB/niD81uMA/mSWyXIn8KDIy
CPY6jiZ4qiIJnQWhWm1Cazv6O7wjDisvB1cCJhDvBv42KkFwtigt5MQnBEGOI2LD
iKCkXfj33E5B6n0sEel68WgYi6rx2tsR9lzAjCRF+jgNd7FfeUi999m7ykgEACR5
OYRqkVcIXz30r9RxQyFqZLNzyO9oaVZpex8ZbWwEzNXG2ccddnMJ
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAw2yv4izfNCAZxlG8wOABZeCkBF+kQq3srYZ3zkpyHEEkz/io
3rGTBYLBldC7Xg8XgifpKuGKEvglu6I7zhM98YwoKOLRXXr8/GaHjtEQUCGwEWz2
pKODlwur1rOix8AkdGg1qPR30tVLrG/IO+3LET0ZTQNwxkfHXEU4hAXXx0uiYf+1
e14g5WsT14/oiGPD8gqjn4L+HJQ7de0fnXp3Q7IGMW5mWqHa6aTaHDECMlGgyMCO
A2TmvJ0GJPbrlIZIgBQEATuuNm8ejSNKg7uSoLTJm2kurPqzJ6y/HnmTonKn3+l6
AurZOhhPBaOImJMadoAIk7IoGksKTUVobqSElQIDAQABAoIBAGr/2HFjFjbpGJOw
b0O/oqRQUh2e7EYiCoOcK37E3iPAO1KvmG6OFayfwjSwG9bNNpbqGU2EPeBTA/3v
PwV/HZxinB5+yhl/3IKp9LDqoR7uwwNXgNf2O3d5SXX91zO9bXhbEn5WlEDYzl00
uxKtCVF//ZlgN+AoruxDbkVDGbkhKHGzvqOW+BWwbYHPOttQ9TQx2ss5+DekpDFV
/FuvXGOcSSV/N+WbDwsqUiM8ovkcflEgQjZYlAY4Ro2U2buf3fKEmy1jxSznNp30
QA4WyYypyS8Hz6S/F4nsjtS3ufCurrWBv4vt2qB+8tH//07NUacjQWZdvEAtaJ+G
IyJgsOUCgYEA38b2SQiw74fwoK6so2XdpCzOObLQBOT1aeZQjt3v8XZ0MPzwWJZm
VkMBmolcEw24xA3jHhOQYafAGjRdaKxlRbJyGJqwENfAs7hO5JSLLWWXsorJQcb7
1OVTFPt7NZopx2Kw7kGGuj9884w57cSl9lsuMptqk8W7pbTo5opOfl8CgYEA35CR
x23kaFDh8+zKUuSdIrkUJ66cazgOfF0FYKiDewd1sGEdZT+gq7Wo8Hi8cp9q+Kuq
MkGrTzu21yMi2fo7RKoSOtV4RQViu6PuoYR/KvRq4F4abHEAivAG4xhPQife84IB
NkDQXaE9EXTP7DXPwj4HV8CnC9LC2qPFU7GVeYsCgYBWPK6c5qSJKrIouif9sDwC
EOJIighwWmvZK9DPvefB/gw49MEK4qr9g0US8Oxyy07w/wkPhiqV97eoYZW9yPIe
Me6WXMaNNxgkKlr86+HW1NfpDmMQ3kYefWHPLDsHJSoElJvqtYXeMKlOkjOg1a+/
iNP83Lftyr3N1jIK5jHpsQKBgE1+clm7qOnT547C7JrxLdrEZs0ehI/R3YuUPvHz
V6gEvPHHqAXZmVsL3CSG5WOiCNVrw9Ip2zTa0RUf08vVJkg1353PMyJRrJi4SVZp
dB8ym/1sASLHxNVkQC7l1UtsQKcN0Fe6/b8GzgFICW6qdHqzP55WZFD/3JUnIZZS
PyrjAoGBAMfuE0Nrw9Fq7f8+U/SsqiW9djJp4R34EF5n8qHkotfRoAbGktCGxLoF
QMbB9X0ibRMpxEKPHj+V0FXu9zUKFuqoriRc3alQYLNzJEdKeQQ/AN5xjG3ilM6D
/FunImbvSdJLjR9Ue6vlFdOquHevBCFDiHOJPQJ/y4qyZR5Avluw
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,25 @@
{
"name": "openvidu-mvc-node",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/OpenVidu/openvidu-tutorials.git"
},
"author": "openvidu@gmail.com",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/OpenVidu/openvidu-tutorials/issues"
},
"homepage": "https://github.com/OpenVidu/openvidu-tutorials#readme",
"dependencies": {
"body-parser": "^1.17.2",
"ejs": "^2.5.6",
"express": "^4.15.3",
"express-session": "^1.15.3"
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,29 @@
#publisher {
float: left;
width: 20%;
margin: 10px;
}
#subscriber {
float: left;
width: 20%;
margin: 10px;
}
video {
width: 100%;
height: auto;
}
table {
border: 0;
}
th {
text-align: left;
}
td {
text-align: left;
padding-right: 15px;
}

290
openvidu-mvc-node/server.js Normal file
View File

@ -0,0 +1,290 @@
// Check launch arguments
if (process.argv.length != 4) {
console.log("Usage: node " + __filename + " OPENVIDU_URL OPENVIDU_SECRET");
process.exit(-1);
}
// For demo purposes we ignore self-signed certificate
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
// Imports
var express = require('express');
var fs = require('fs');
var session = require('express-session');
var https = require('https');
var bodyParser = require('body-parser'); // pull information from HTML POST (express4)
var app = express(); // create our app w/ express
// Configuration
app.use(session({
saveUninitialized: true,
resave: false,
secret: 'MY_SECRET'
}));
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
app.use(bodyParser.urlencoded({
'extended': 'true'
})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({
type: 'application/vnd.api+json'
})); // parse application/vnd.api+json as json
app.set('view engine', 'ejs'); // Embedded JavaScript as template engine
// listen (start app with node server.js)
var options = {
key: fs.readFileSync('openvidukey.pem'),
cert: fs.readFileSync('openviducert.pem')
};
https.createServer(options, app).listen(5000);
console.log("App listening on port https://[]:5000");
// Environment variables
var OPENVIDU_URL = process.argv[2];
var OPENVIDU_SECRET = process.argv[3];
// Mock database
var users = [{
user: "publisher1",
pass: "pass",
role: "PUBLISHER"
}, {
user: "publisher2",
pass: "pass",
role: "PUBLISHER"
}, {
user: "subscriber",
pass: "pass",
role: "SUBSCRIBER"
}];
// Objects for storing active sessions and users
var mapSessionNameSessionId = {};
var mapSessionIdsTokens = {};
// APIRest
app.get('/', (req, res) => {
if (req.session.loggedUser) { // User is logged in: redirect to '/dashboard'
res.render('dashboard.ejs', {
user: req.session.loggedUser
});
} else { // User is not logged in: redirect to '/'
req.session.destroy();
res.render('index.ejs');
}
});
app.post('/', (req, res) => {
if (req.session.loggedUser && (req.body.islogout == 'true')) { // User wants to logout
console.log("'" + req.session.loggedUser + "' has logged out");
req.session.destroy();
}
res.render('index.ejs');
});
app.post('/dashboard', dashboardController);
app.get('/dashboard', dashboardController);
function dashboardController(req, res) {
if (isLogged(req.session)) {
user = req.session.loggedUser;
res.render('dashboard.ejs', {
user: user
});
} else {
var user = req.body.user;
var pass = req.body.pass;
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
if (login(user, pass)) {
console.log("'" + user + "' has logged in");
req.session.loggedUser = user;
res.render('dashboard.ejs', {
user: user
});
} else {
console.log("'" + user + "' invalid credentials");
req.session.destroy();
res.render('index.ejs');
}
}
}
app.post('/session', (req, res) => {
if (!isLogged(req.session)) {
req.session.destroy();
res.render('index.ejs');
} else {
var clientData = req.body.data;
var sessionName = req.body.sessionname;
var role = users.find(u => (u.user === req.session.loggedUser)).role;
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
var sessionId = mapSessionNameSessionId[sessionName];
if (sessionId) {
console.log('Existing session ' + sessionName);
getToken(sessionId, role, serverData, function (token) {
mapSessionIdsTokens[sessionId].push(token);
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.render('session.ejs', {
sessionId: sessionId,
token: token,
nickName: clientData,
userName: req.session.loggedUser,
sessionName: sessionName
});
});
} else {
console.log('New session ' + sessionName);
getSessionId(function (sessionId) {
mapSessionNameSessionId[sessionName] = sessionId;
mapSessionIdsTokens[sessionId] = [];
getToken(sessionId, role, serverData, function (token) {
mapSessionIdsTokens[sessionId].push(token);
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.render('session.ejs', {
sessionId: sessionId,
token: token,
nickName: clientData,
userName: req.session.loggedUser,
sessionName: sessionName
});
});
});
}
}
});
app.post('/leave-session', (req, res) => {
if (!isLogged(req.session)) {
req.session.destroy();
res.render('index.ejs');
} else {
var sessionName = req.body.sessionname;
var token = req.body.token;
console.log('Removing user | {sessionName, token}={' + sessionName + ', ' + token + '}');
var sessionId = mapSessionNameSessionId[sessionName];
if (sessionId) {
var tokens = mapSessionIdsTokens[sessionId];
if (tokens) {
var index = tokens.indexOf(token);
if (index !== -1) { // User left the session
tokens.splice(index, 1);
console.log(sessionName + ': ' + mapSessionIdsTokens[sessionId].toString());
} else {
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
console.log(msg);
res.render('dashboard.ejs', {
user: req.session.loggedUser
});
}
if (mapSessionIdsTokens[sessionId].length == 0) { // Last user left the session
console.log(sessionName + ' empty!');
delete mapSessionNameSessionId[sessionName];
}
res.render('dashboard.ejs', {
user: req.session.loggedUser
});
} else {
var msg = 'Problems in the app server: the SESSIONID wasn\'t valid';
console.log(msg);
res.render('dashboard.ejs', {
user: req.session.loggedUser
});
}
} else {
var msg = 'Problems in the app server: the SESSION does not exist';
console.log(msg);
res.render('dashboard.ejs', {
user: req.session.loggedUser
});
}
}
});
function login(user, pass) {
return (user != null &&
pass != null &&
users.find(u => (u.user === user) && (u.pass === pass)));
}
function isLogged(session) {
return (session.loggedUser != null);
}
function getBasicAuth() {
return 'Basic ' + (new Buffer('OPENVIDUAPP:' + OPENVIDU_SECRET).toString('base64'));
}
// HTTP request to OpenVidu Server to get a sessionId
function getSessionId(callback) {
var options = {
hostname: OPENVIDU_URL,
port: 8443,
path: '/api/sessions',
method: 'POST',
headers: {
'Authorization': getBasicAuth()
}
};
const req = https.request(options, (res) => {
var body = '';
res.on('data', (d) => {
// Continuously update stream with data
body += d;
});
res.on('end', function () {
// Data reception is done
var parsed = JSON.parse(body);
callback(parsed.id);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
}
// HTTP request to OpenVidu Server to get a token
function getToken(sessionId, role, data, callback) {
var requestBody = JSON.stringify({
'session': sessionId,
'role': role,
'data': data
});
var options = {
hostname: OPENVIDU_URL,
port: 8443,
path: '/api/tokens',
method: 'POST',
headers: {
'Authorization': getBasicAuth(),
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(requestBody)
}
};
const req = https.request(options, (res) => {
var body = '';
res.on('data', (d) => {
// Continuously update stream with data
body += d;
});
res.on('end', function () {
// Data reception is done
var parsed = JSON.parse(body);
callback(parsed.token);
});
});
req.on('error', (e) => {
console.error(e);
});
req.write(requestBody);
req.end();
}

Some files were not shown because too many files have changed in this diff Show More