'Connection' class implemented in openvidu-browser

pull/20/head
pabloFuente 2017-05-17 11:46:32 +02:00
parent 7a55aa7baf
commit 790cd25c35
11 changed files with 199 additions and 112 deletions

View File

@ -6,6 +6,7 @@
"types": "lib/OpenVidu/index.d.ts", "types": "lib/OpenVidu/index.d.ts",
"scripts": { "scripts": {
"browserify": "cd ts/OpenVidu && browserify Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../../static/js/OpenVidu.js -v", "browserify": "cd ts/OpenVidu && browserify Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../../static/js/OpenVidu.js -v",
"updatets": "cd ts/OpenViduInternal && tsc && cd ../OpenVidu && tsc",
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"prepublish": "cd ts && tsc", "prepublish": "cd ts && tsc",
"developing": "cd ts && tsc -w" "developing": "cd ts && tsc -w"

File diff suppressed because one or more lines are too long

View File

@ -1,21 +1,33 @@
import { SessionInternal, SessionOptions } from '../OpenViduInternal/SessionInternal'; import { SessionInternal, SessionOptions } from '../OpenViduInternal/SessionInternal';
import { Stream } from '../OpenViduInternal/Stream'; import { Stream } from '../OpenViduInternal/Stream';
import { Connection } from "../OpenViduInternal/Connection";
import { OpenVidu } from './OpenVidu'; import { OpenVidu } from './OpenVidu';
import { Publisher} from './Publisher'; import { Publisher} from './Publisher';
import { Subscriber } from './Subscriber'; import { Subscriber } from './Subscriber';
import EventEmitter = require('wolfy87-eventemitter');
export class Session { export class Session {
//capabilities: Capabilities
//connection: Connection
sessionId: String; sessionId: String;
//capabilities: Capabilities
connection: Connection;
private ee = new EventEmitter();
constructor(private session: SessionInternal, private openVidu: OpenVidu) { constructor(private session: SessionInternal, private openVidu: OpenVidu) {
this.sessionId = session.getSessionId(); this.sessionId = session.getSessionId();
// Listens to the deactivation of the default behaviour upon the deletion of a Stream object
this.session.addEventListener('stream-removed-default', event => { this.session.addEventListener('stream-removed-default', event => {
event.stream.removeVideo(); event.stream.removeVideo();
}); });
// Sets or updates the value of 'connection' property. Triggered by SessionInternal when succesful connection
this.session.addEventListener('update-connection-object', event => {
this.connection = event.connection;
});
} }
connect(token: string, callback: any); connect(token: string, callback: any);

View File

@ -3,3 +3,4 @@ export * from './Session';
export * from './Publisher'; export * from './Publisher';
export * from './Subscriber'; export * from './Subscriber';
export * from '../OpenViduInternal/Stream'; export * from '../OpenViduInternal/Stream';
export * from '../OpenViduInternal/Connection';

View File

@ -5,25 +5,26 @@ import { SessionInternal } from './SessionInternal';
type ObjMap<T> = { [s: string]: T; } type ObjMap<T> = { [s: string]: T; }
export interface ParticipantOptions { export interface ConnectionOptions {
id: string; id: string;
metadata: string; metadata: string;
streams?: StreamOptions[]; streams?: StreamOptions[];
} }
export class ParticipantInternal { export class Connection {
private id: string; public connectionId: string;
private metadata: string; public data: string;
public creationTime: number;
private streams: ObjMap<Stream> = {}; private streams: ObjMap<Stream> = {};
private streamsOpts: StreamOptions[] = []; private streamsOpts: StreamOptions[] = [];
constructor( private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, private options?: ParticipantOptions ) { constructor( private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, private options?: ConnectionOptions ) {
if ( options ) { if ( options ) {
this.id = options.id; this.connectionId = options.id;
this.metadata = options.metadata; this.data = options.metadata;
if ( options.streams ) { if ( options.streams ) {
@ -47,12 +48,12 @@ export class ParticipantInternal {
} }
} }
console.log( "New " + ( local ? "local " : "remote " ) + "participant " + this.id console.log( "New " + ( local ? "local " : "remote " ) + "participant " + this.connectionId
+ ", streams opts: ", this.streamsOpts ); + ", streams opts: ", this.streamsOpts );
} }
setId( newId ) { setId( newId ) {
this.id = newId; this.connectionId = newId;
} }
addStream( stream: Stream ) { addStream( stream: Stream ) {
@ -71,7 +72,7 @@ export class ParticipantInternal {
} }
getId() { getId() {
return this.id; return this.connectionId;
} }
sendIceCandidate( candidate ) { sendIceCandidate( candidate ) {

View File

@ -1,6 +1,6 @@
import { Stream } from './Stream'; import { Stream } from './Stream';
import { OpenViduInternal } from './OpenViduInternal'; import { OpenViduInternal } from './OpenViduInternal';
import { ParticipantInternal, ParticipantOptions } from './ParticipantInternal'; import { Connection, ConnectionOptions } from './Connection';
import EventEmitter = require('wolfy87-eventemitter'); import EventEmitter = require('wolfy87-eventemitter');
export interface SessionOptions { export interface SessionOptions {
@ -18,16 +18,16 @@ export class SessionInternal {
private ee = new EventEmitter(); private ee = new EventEmitter();
private streams = {}; private streams = {};
private participants = {}; private participants = {};
private participantsSpeaking: ParticipantInternal[] = []; private participantsSpeaking: Connection[] = [];
private connected = false; private connected = false;
private localParticipant: ParticipantInternal; public localParticipant: Connection;
private subscribeToStreams: boolean; private subscribeToStreams: boolean;
private updateSpeakerInterval: number; private updateSpeakerInterval: number;
public thresholdSpeaker: number; public thresholdSpeaker: number;
private options: SessionOptions private options: SessionOptions
constructor(private openVidu: OpenViduInternal, private sessionId: string) { constructor(private openVidu: OpenViduInternal, private sessionId: string) {
this.localParticipant = new ParticipantInternal(this.openVidu, true, this); this.localParticipant = new Connection(this.openVidu, true, this);
} }
@ -66,15 +66,16 @@ export class SessionInternal {
let exParticipants = response.value; let exParticipants = response.value;
let roomEvent = { let roomEvent = {
participants: new Array<ParticipantInternal>(), participants: new Array<Connection>(),
streams: new Array<Stream>() streams: new Array<Stream>()
} }
let length = exParticipants.length; let length = exParticipants.length;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
let participant = new ParticipantInternal(this.openVidu, false, this, let participant = new Connection(this.openVidu, false, this,
exParticipants[i]); exParticipants[i]);
participant.creationTime = new Date().getTime();
this.participants[participant.getId()] = participant; this.participants[participant.getId()] = participant;
@ -89,6 +90,16 @@ export class SessionInternal {
} }
} }
// Update local Connection object properties with values returned by server
this.localParticipant.data = response.metadata;
this.localParticipant.creationTime = new Date().getTime();
// Updates the value of property 'connection' in Session object
this.ee.emitEvent('update-connection-object', [{ connection: this.localParticipant }]);
// Own connection created event
this.ee.emitEvent('connectionCreated', [{ connection: this.localParticipant }]);
// One connection created event for each existing participant in the session
for (let part of roomEvent.participants) { for (let part of roomEvent.participants) {
this.ee.emitEvent('connectionCreated', [{ connection: part }]); this.ee.emitEvent('connectionCreated', [{ connection: part }]);
} }
@ -191,7 +202,9 @@ export class SessionInternal {
onParticipantPublished(options) { onParticipantPublished(options) {
let participant = new ParticipantInternal(this.openVidu, false, this, options); options.metadata = this.participants[options.id].data;
let participant = new Connection(this.openVidu, false, this, options);
let pid = participant.getId(); let pid = participant.getId();
if (!(pid in this.participants)) { if (!(pid in this.participants)) {
@ -200,6 +213,7 @@ export class SessionInternal {
console.log("Publisher found in participants list by its id", pid); console.log("Publisher found in participants list by its id", pid);
} }
//replacing old participant (this one has streams) //replacing old participant (this one has streams)
participant.creationTime = this.participants[pid].creationTime;
this.participants[pid] = participant; this.participants[pid] = participant;
this.ee.emitEvent('participant-published', [{ participant }]); this.ee.emitEvent('participant-published', [{ participant }]);
@ -219,7 +233,8 @@ export class SessionInternal {
onParticipantJoined(msg) { onParticipantJoined(msg) {
let participant = new ParticipantInternal(this.openVidu, false, this, msg); let participant = new Connection(this.openVidu, false, this, msg);
participant.creationTime = new Date().getTime();
let pid = participant.getId(); let pid = participant.getId();
if (!(pid in this.participants)) { if (!(pid in this.participants)) {
@ -270,6 +285,10 @@ export class SessionInternal {
participant.dispose(); participant.dispose();
this.ee.emitEvent('connectionDestroyed', [{
connection: participant
}]);
} else { } else {
console.warn("Participant " + msg.name console.warn("Participant " + msg.name
+ " unknown. Participants: " + " unknown. Participants: "

View File

@ -5,7 +5,7 @@
* *
* stream.hasAudio(); stream.hasVideo(); stream.hasData(); * stream.hasAudio(); stream.hasVideo(); stream.hasData();
*/ */
import { ParticipantInternal } from './ParticipantInternal'; import { Connection } from './Connection';
import { SessionInternal } from './SessionInternal'; import { SessionInternal } from './SessionInternal';
import { OpenViduInternal, Callback } from './OpenViduInternal'; import { OpenViduInternal, Callback } from './OpenViduInternal';
import EventEmitter = require('wolfy87-eventemitter'); import EventEmitter = require('wolfy87-eventemitter');
@ -33,7 +33,7 @@ function hide(id: string) {
export interface StreamOptions { export interface StreamOptions {
id: string; id: string;
participant: ParticipantInternal; participant: Connection;
recvVideo: any; recvVideo: any;
recvAudio: any; recvAudio: any;
video: boolean; video: boolean;
@ -56,7 +56,7 @@ export class Stream {
private video: HTMLVideoElement; private video: HTMLVideoElement;
private videoElements: VideoOptions[] = []; private videoElements: VideoOptions[] = [];
private elements: HTMLDivElement[] = []; private elements: HTMLDivElement[] = [];
private participant: ParticipantInternal; private participant: Connection;
private speechEvent: any; private speechEvent: any;
private recvVideo: any; private recvVideo: any;
private recvAudio: any; private recvAudio: any;

View File

@ -1,4 +1,4 @@
export * from './OpenViduInternal'; export * from './OpenViduInternal';
export * from './ParticipantInternal'; export * from './Connection';
export * from './SessionInternal'; export * from './SessionInternal';
export * from './Stream'; export * from './Stream';

View File

@ -42,10 +42,12 @@ export class VideoSessionComponent implements OnInit {
// 0) Obtain 'sessionId' and 'token' from server // 0) Obtain 'sessionId' and 'token' from server
// In this case, the method ngOnInit takes care of it // In this case, the method ngOnInit takes care of it
// 1) Initialize OpenVidu and your Session // 1) Initialize OpenVidu and your Session
this.OV = new OpenVidu("wss://" + location.hostname + ":8443/"); this.OV = new OpenVidu("wss://" + location.hostname + ":8443/");
this.session = this.OV.initSession("apikey", this.sessionId); this.session = this.OV.initSession("apikey", this.sessionId);
// 2) Specify the actions when events take place // 2) Specify the actions when events take place
this.session.on('streamCreated', (event) => { this.session.on('streamCreated', (event) => {
this.session.subscribe(event.stream, 'subscriber', { this.session.subscribe(event.stream, 'subscriber', {
@ -55,10 +57,27 @@ export class VideoSessionComponent implements OnInit {
}); });
}); });
this.session.on('streamDestroyed', (event) => {
console.warn("STREAM DESTROYED!");
console.warn(event.stream);
});
this.session.on('connectionCreated', (event) => { this.session.on('connectionCreated', (event) => {
if (event.connection.connectionId == this.session.connection.connectionId){
console.warn("YOUR OWN CONNECTION CREATED!");
} else {
console.warn("OTHER USER'S CONNECTION CREATED!");
}
console.warn(event); console.warn(event);
}); });
this.session.on('connectionDestroyed', (event) => {
console.warn("OTHER USER'S CONNECTION DESTROYED!");
console.warn(event);
});
// 3) Connect to the session // 3) Connect to the session
this.session.connect(this.token, "CLIENT:" + this.authenticationService.getCurrentUser().name ,(error) => { this.session.connect(this.token, "CLIENT:" + this.authenticationService.getCurrentUser().name ,(error) => {

View File

@ -33,6 +33,8 @@ public class UserParticipant {
super(); super();
this.participantId = participantId; this.participantId = participantId;
this.userName = userName; this.userName = userName;
this.clientMetadata = "";
this.serverMetadata = "";
this.streaming = streaming; this.streaming = streaming;
} }
@ -91,6 +93,10 @@ public class UserParticipant {
this.streaming = streaming; this.streaming = streaming;
} }
public String getFullMetadata(){
return this.clientMetadata + "-/-" + this.serverMetadata;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View File

@ -62,7 +62,8 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
return; return;
} }
JsonArray result = new JsonArray(); JsonObject result = new JsonObject();
JsonArray resultArray = new JsonArray();
for (UserParticipant participant : existingParticipants) { for (UserParticipant participant : existingParticipants) {
JsonObject participantJson = new JsonObject(); JsonObject participantJson = new JsonObject();
participantJson participantJson
@ -79,17 +80,21 @@ public class DefaultNotificationRoomHandler implements NotificationRoomHandler {
streamsArray.add(stream); streamsArray.add(stream);
participantJson.add(ProtocolElements.JOINROOM_PEERSTREAMS_PARAM, streamsArray); participantJson.add(ProtocolElements.JOINROOM_PEERSTREAMS_PARAM, streamsArray);
} }
result.add(participantJson); resultArray.add(participantJson);
JsonObject notifParams = new JsonObject(); JsonObject notifParams = new JsonObject();
// Metadata associated to new participant // Metadata associated to new participant
notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, newParticipant.getUserName()); notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, newParticipant.getUserName());
notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, newParticipant.getClientMetadata() + "--" + newParticipant.getServerMetadata()); notifParams.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, newParticipant.getFullMetadata());
notifService.sendNotification(participant.getParticipantId(), notifService.sendNotification(participant.getParticipantId(),
ProtocolElements.PARTICIPANTJOINED_METHOD, notifParams); ProtocolElements.PARTICIPANTJOINED_METHOD, notifParams);
} }
result.addProperty(ProtocolElements.PARTICIPANTJOINED_USER_PARAM, newParticipant.getUserName());
result.addProperty(ProtocolElements.PARTICIPANTJOINED_METADATA_PARAM, newParticipant.getFullMetadata());
result.add("value", resultArray);
notifService.sendResponse(request, result); notifService.sendResponse(request, result);
} }