Code matching tutorials

This commit is contained in:
pabloFuente 2017-09-01 14:16:42 +02:00
parent 4fbf9a6a6e
commit 442499bf01
13 changed files with 300 additions and 113 deletions

View File

@ -1,21 +1,22 @@
var OV;
var session;
var publisher;
var sessionId;
var audioEnabled = true;
var videoEnabled = true;
var numOfVideos = 0;
var OV; // OpenVidu object to initialize a session
var session; // Session object where the user will connect
var publisher; // Publisher object which the user will publish
var sessionId; // Unique identifier of the session
var audioEnabled = true; // True if the audio track of publisher is active
var videoEnabled = true; // True if the video track of publisher is active
var numOfVideos = 0; // Keeps track of the number of videos that are being shown
// Check if the URL already has a room
window.addEventListener('load', function () {
sessionId = window.location.hash;
sessionId = window.location.hash; // For 'https://myurl/#roomId', sessionId would be '#roomId'
if (sessionId) {
// The URL has a session id
// The URL has a session id. Join the room right away
console.log("Joining to room " + sessionId);
showSessionHideJoin();
joinRoom(sessionId);
} else {
// The URL has not a session id. Show welcome page
showJoinHideSession();
}
});
@ -38,11 +39,11 @@ function joinRoom(sessionId) {
// --- 1) Get an OpenVidu object and init a session with a sessionId ---
// Init OpenVidu object
OV = new OpenVidu();
// We will join the video-call "sessionId". This parameter must start with the URL of OpenVidu Server, with secure WebSocket protocol ('wss://')
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + '?secret=MY_SECRET');
// We will join the video-call "sessionId". As there's no server, this parameter must start with the URL of
// OpenVidu Server (with secure websocket protocol: "wss://") and must include the OpenVidu secret at the end
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + "?secret=MY_SECRET");
// --- 2) Specify the actions when events take place ---
@ -51,6 +52,7 @@ function joinRoom(sessionId) {
session.on('streamCreated', function (event) {
// Subscribe to the Stream to receive it. HTML video will be appended to element with 'subscriber' id
var subscriber = session.subscribe(event.stream, 'videos');
// When the new video is added to DOM, update the page layout to fit one more participant
subscriber.on('videoElementCreated', function (event) {
numOfVideos++;
updateLayout();
@ -59,6 +61,7 @@ function joinRoom(sessionId) {
// On every new Stream destroyed...
session.on('streamDestroyed', function (event) {
// Update the page layout
numOfVideos--;
updateLayout();
});
@ -66,8 +69,7 @@ function joinRoom(sessionId) {
// --- 3) Connect to the session ---
// 'token' param irrelevant when using insecure version of OpenVidu. Second param will be received by every user
// in Stream.connection.data property, which will be appended to DOM as the user's nickname
// Remember 'userId' param (usually called 'token') is irrelevant when using the insecure version of OpenVidu
session.connect(userId, function (error) {
// If the connection is successful, initialize a publisher and publish to the session
@ -82,9 +84,10 @@ function joinRoom(sessionId) {
});
publisher.on('videoElementCreated', function (event) {
// When your own video is added to DOM, update the page layout to fit it
numOfVideos++;
updateLayout();
$(event.element).prop('muted', true);
$(event.element).prop('muted', true); // Mute local video
});
// --- 5) Publish your stream ---
@ -96,9 +99,11 @@ function joinRoom(sessionId) {
}
});
// Update the URL shown in the browser's navigation bar to show the session id
var pathname = (location.pathname.slice(-1) === "/" ? location.pathname : location.pathname+"/");
window.history.pushState("", "", pathname + sessionId);
// Auxiliary methods to show the session's view
showSessionHideJoin();
initializeSessionView();
@ -107,7 +112,7 @@ function joinRoom(sessionId) {
function leaveRoom() {
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
session.disconnect();

View File

@ -46,15 +46,18 @@ public class LoginController {
public ResponseEntity<Object> login(@RequestBody String userPass, HttpSession httpSession) throws ParseException {
System.out.println("Logging in | {user, pass}=" + userPass);
// Retrieve params from POST body
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");
if (login(user, pass)) { // Correct user-pass
// Validate session and return OK
// Value stored in HttpSession allows us to identify the user in future requests
httpSession.setAttribute("loggedUser", user);
return new ResponseEntity<>(HttpStatus.OK);
} else {
} else { // Wrong user-pass
// Invalidate session and return error
httpSession.invalidate();
return new ResponseEntity<>("User/Pass incorrect", HttpStatus.UNAUTHORIZED);
}

View File

@ -51,10 +51,18 @@ public class SessionController {
System.out.println("Getting sessionId and token | {sessionName}=" + sessionNameParam);
JSONObject sessionJSON = (JSONObject) new JSONParser().parse(sessionNameParam);
// The video-call to connect ("TUTORIAL")
String sessionName = (String) sessionJSON.get("session");
// Role associated to this user
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
// Optional data to be passed to other users when this user connects to the video-call
// In this case, a JSON with the value we stored in the HttpSession object on login
String serverData = "{\"serverData\": \"" + httpSession.getAttribute("loggedUser") + "\"}";
// Build tokenOptions object with the serverData and the role
TokenOptions tokenOptions = new TokenOptions.Builder().data(serverData).role(role).build();
JSONObject responseJson = new JSONObject();
@ -63,16 +71,25 @@ public class SessionController {
// Session already exists: return existing sessionId and a new token
System.out.println("Existing session " + sessionName);
try {
// Get the existing sessionId from our collection with
// the sessionName param ("TUTORIAL")
String sessionId = this.mapSessions.get(sessionName).getSessionId();
// Generate a new token with the recently created tokenOptions
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
// Update our collection storing the new token
this.mapSessionIdsTokens.get(sessionId).put(token, role);
// Prepare the response with the sessionId and the token
responseJson.put(0, sessionId);
responseJson.put(1, token);
// Return the response to the client
return new ResponseEntity<>(responseJson, HttpStatus.OK);
} catch (Exception e) {
// If error generate an error message and return it to client
return getErrorResponse(e);
}
@ -80,19 +97,28 @@ public class SessionController {
// New session: return a new sessionId and token
System.out.println("New session " + sessionName);
try {
// Create a new OpenVidu Session
Session session = this.openVidu.createSession();
// Get the sessionId
String sessionId = session.getSessionId();
// Generate a new token with the recently created tokenOptions
String token = session.generateToken(tokenOptions);
// Store the session and the token in our collections
this.mapSessions.put(sessionName, session);
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
this.mapSessionIdsTokens.get(sessionId).put(token, role);
// Prepare the response with the sessionId and the token
responseJson.put(0, sessionId);
responseJson.put(1, token);
// Return the response to the client
return new ResponseEntity<>(responseJson, HttpStatus.OK);
} catch (Exception e) {
// If error generate an error message and return it to client
return getErrorResponse(e);
}
}
@ -109,30 +135,36 @@ public class SessionController {
}
System.out.println("Removing user | {sessionName, token}=" + sessionNameToken);
// Retrieve the params from BODY
JSONObject sessionNameTokenJSON = (JSONObject) new JSONParser().parse(sessionNameToken);
String sessionName = (String) sessionNameTokenJSON.get("sessionName");
String token = (String) sessionNameTokenJSON.get("token");
// If the session exists ("TUTORIAL" in this case)
if (this.mapSessions.get(sessionName) != null) {
String sessionId = this.mapSessions.get(sessionName).getSessionId();
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
// If the token exists
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
// User left the session
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
// Last user left the session
// Last user left: session must be removed
this.mapSessions.remove(sessionName);
}
return new ResponseEntity<>(HttpStatus.OK);
} else {
// The TOKEN wasn't valid
System.out.println("Problems in the app server: the TOKEN wasn't valid");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
} else {
// The SESSIONID wasn't valid
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
} else {
// The SESSION does not exist
System.out.println("Problems in the app server: the SESSION does not exist");
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}

View File

@ -73,7 +73,7 @@ function joinSession() {
};
initMainVideo(event.element, userData);
appendUserData(event.element, userData);
$(event.element).prop('muted', true);
$(event.element).prop('muted', true); // Mute local video
});
@ -116,17 +116,18 @@ function leaveSession() {
/* APPLICATION BACKEND METHODS */
/* APPLICATION REST METHODS */
function logIn() {
var user = $("#user").val();
userName = user;
var pass = $("#pass").val();
var jsonBody = JSON.stringify({
var user = $("#user").val(); // Username
var pass = $("#pass").val(); // Password
var jsonBody = JSON.stringify({ // Body of POST request
'user': user,
'pass': pass
});
userName = user;
httpRequest('POST', 'api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
console.warn(userName + ' login');
$("#name-user").text(user);
@ -147,26 +148,30 @@ function logOut() {
}
function getSessionIdAndToken(callback) {
nickName = $("#participantName").val();
sessionName = $("#sessionName").val();
var jsonBody = JSON.stringify({
sessionName = $("#sessionName").val(); // Video-call chosen by the user
nickName = $("#participantName").val(); // Nickname chosen by the user
var jsonBody = JSON.stringify({ // Body of POST request
'session': sessionName
});
// Send POST request
httpRequest('POST', 'api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
sessionId = response[0];
token = response[1];
sessionId = response[0]; // Get sessionId from response
token = response[1]; // Get token from response
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
callback();
callback(); // Continue the join operation
});
}
function removeUser() {
// Body of POST request with the name of the session and the token of the leaving user
var jsonBody = JSON.stringify({
'sessionName': sessionName,
'token': token
});
// Send POST request
httpRequest('POST', 'api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
console.warn(userName + " correctly removed from session");
});
@ -195,7 +200,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
}
}
/* APPLICATION BACKEND METHODS */
/* APPLICATION REST METHODS */

View File

@ -27,11 +27,11 @@ function joinSession() {
// Subscribe to the Stream to receive it
// HTML video will be appended to element with 'video-container' id
var subscriber = session.subscribe(event.stream, 'video-container');
// When the HTML video has been appended to DOM...
subscriber.on('videoElementCreated', function (event) {
// Add a new HTML element for the user's name and nickname over its video
// Add a new <p> element for the user's name and nickname just below its video
appendUserData(event.element, subscriber.stream.connection);
});
});
@ -42,6 +42,7 @@ function joinSession() {
removeUserData(event.stream.connection);
});
// --- 3) Connect to the session passing the retrieved token and some more data from
// the client (in this case a JSON with the nickname chosen by the user) ---
@ -73,7 +74,7 @@ function joinSession() {
};
initMainVideo(event.element, userData);
appendUserData(event.element, userData);
$(event.element).prop('muted', true);
$(event.element).prop('muted', true); // Mute lcoal video
});
@ -116,18 +117,19 @@ function leaveSession() {
/* APPLICATION BACKEND METHODS */
/* APPLICATION REST METHODS */
function logIn() {
var user = $("#user").val();
userName = user;
var pass = $("#pass").val();
var jsonBody = JSON.stringify({
var user = $("#user").val(); // Username
var pass = $("#pass").val(); // Password
var jsonBody = JSON.stringify({ // Body of POST request
'user': user,
'pass': pass
});
httpRequest('POST', 'api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
userName = user;
httpRequest('POST', '/api-login/login', jsonBody, 'Login WRONG', function successCallback(response){ // Send POST request
console.warn(userName + ' login');
$("#name-user").text(user);
$("#not-logged").hide();
@ -147,26 +149,29 @@ function logOut() {
}
function getSessionIdAndToken(callback) {
nickName = $("#participantName").val();
sessionName = $("#sessionName").val();
var jsonBody = JSON.stringify({
sessionName = $("#sessionName").val(); // Video-call chosen by the user
nickName = $("#participantName").val(); // Nickname chosen by the user
var jsonBody = JSON.stringify({ // Body of POST request
'session': sessionName
});
// Send POST request
httpRequest('POST', 'api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
sessionId = response[0];
token = response[1];
sessionId = response[0]; // Get sessionId from response
token = response[1]; // Get token from response
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
callback();
callback(); // Continue the join operation
});
}
function removeUser() {
// Body of POST request with the name of the session and the token of the leaving user
var jsonBody = JSON.stringify({
'sessionName': sessionName,
'token': token
});
// Send POST request
httpRequest('POST', 'api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
console.warn(userName + " correctly removed from session");
});
@ -195,7 +200,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
}
}
/* APPLICATION BACKEND METHODS */
/* APPLICATION REST METHODS */

View File

@ -60,15 +60,17 @@ var users = [{
}];
// Environment variables
// Environment variable: URL where our OpenVidu server is listening
var OPENVIDU_URL = process.argv[2];
// Environment variable: secret shared with our OpenVidu server
var OPENVIDU_SECRET = process.argv[3];
// OpenVidu object
// OpenVidu object to ask openvidu-server for sessionId and token
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
// Objects for storing active sessions and users
// Collection to pair session names and OpenVidu Session objects
var mapSessionNameSession = {};
// Collection to pair sessionId's (identifiers of Session objects) and tokens
var mapSessionIdTokens = {};
/* CONFIGURATION */
@ -79,15 +81,20 @@ var mapSessionIdTokens = {};
// Login
app.post('/api-login/login', function (req, res) {
// Retrieve params from POST body
var user = req.body.user;
var pass = req.body.pass;
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
if (login(user, pass)) {
if (login(user, pass)) { // Correct user-pass
// Validate session and return OK
// Value stored in req.session allows us to identify the user in future requests
console.log("'" + user + "' has logged in");
req.session.loggedUser = user;
res.status(200).send();
} else {
} else { // Wrong user-pass
// Invalidate session and return error
console.log("'" + user + "' invalid credentials");
req.session.destroy();
res.status(401).send('User/Pass incorrect');
@ -107,22 +114,40 @@ app.post('/api-sessions/get-sessionid-token', function (req, res) {
req.session.destroy();
res.status(401).send('User not logged');
} else {
// The video-call to connect ("TUTORIAL")
var sessionName = req.body.session;
// Role associated to this user
var role = users.find(u => (u.user === req.session.loggedUser)).role;
// Optional data to be passed to other users when this user connects to the video-call
// In this case, a JSON with the value we stored in the req.session object on login
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
// Build tokenOptions object with the serverData and the role
var tokenOptions = new TokenOptions.Builder()
.data(serverData)
.role(role)
.build();
if (mapSessionNameSession[sessionName]) {
// Session already exists: return existing sessionId and a new token
console.log('Existing session ' + sessionName);
// Get the existing Session from the collection
var mySession = mapSessionNameSession[sessionName];
// Generate a new token asynchronously with the recently created tokenOptions
mySession.generateToken(tokenOptions, function (token) {
// Get the existing sessionId
var sessionId = mySession.getSessionId();
// Store the new token in the collection of tokens
mapSessionIdTokens[sessionId].push(token);
// Return the sessionId and token to the client
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.status(200).send({
@ -130,17 +155,28 @@ app.post('/api-sessions/get-sessionid-token', function (req, res) {
1: token
});
});
} else {
} else { // New session: return a new sessionId and a new token
// Create a new OpenVidu Session
console.log('New session ' + sessionName);
var mySession = OV.createSession();
// Get the sessionId asynchronously
mySession.getSessionId(function (sessionId) {
// Store the new Session in the collection of Sessions
mapSessionNameSession[sessionName] = mySession;
// Store a new empty array in the collection of tokens
mapSessionIdTokens[sessionId] = [];
// Generate a new token asynchronously with the recently created tokenOptions
mySession.generateToken(tokenOptions, function (token) {
// Store the new token in the collection of tokens
mapSessionIdTokens[sessionId].push(token);
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
// Return the sessionId and token to the client
res.status(200).send({
0: sessionId,
1: token
@ -157,16 +193,21 @@ app.post('/api-sessions/remove-user', function (req, res) {
req.session.destroy();
res.status(401).send('User not logged');
} else {
// Retrieve params from POST body
var sessionName = req.body.sessionName;
var token = req.body.token;
console.log('Removing user | {sessionName, token}={' + sessionName + ", " + token + '}');
// If the session exists ("TUTORIAL" in this case)
var mySession = mapSessionNameSession[sessionName];
if (mySession) {
var tokens = mapSessionIdTokens[mySession.getSessionId()];
if (tokens) {
var index = tokens.indexOf(token);
if (index !== -1) { // User left the session
// If the token exists
if (index !== -1) {
// Token removed!
tokens.splice(index, 1);
console.log(sessionName + ': ' + mapSessionIdTokens[mySession.getSessionId()].toString());
} else {
@ -174,7 +215,8 @@ app.post('/api-sessions/remove-user', function (req, res) {
console.log(msg);
res.status(500).send(msg);
}
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) { // Last user left the session
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) {
// Last user left: session must be removed
console.log(sessionName + ' empty!');
delete mapSessionNameSession[sessionName];
}

View File

@ -49,20 +49,30 @@ public class LoginController {
@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) {
@RequestParam(name = "pass", required = false) String pass,
Model model, HttpSession httpSession) {
// Check if the user is already logged in
String userName = (String) httpSession.getAttribute("loggedUser");
if (userName != null) { // User is already logged
if (userName != null) {
// User is already logged. Immediately return dashboard
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");
// User wasn't logged and wants to
if (login(user, pass)) { // Correct user-pass
// Validate session and return OK
// Value stored in HttpSession allows us to identify the user in future requests
httpSession.setAttribute("loggedUser", user);
model.addAttribute("username", user);
// Return dashboard.html template
return "dashboard";
} else {
} else { // Wrong user-pass
// Invalidate session and redirect to index.html
httpSession.invalidate();
return "redirect:/";
}

View File

@ -20,12 +20,17 @@ import io.openvidu.java.client.TokenOptions;
@Controller
public class SessionController {
OpenVidu openVidu;
// OpenVidu object to ask openvidu-server for sessionId and token
private OpenVidu openVidu;
// Collection to pair session names and OpenVidu Session objects
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
// Collection to pair sessionId's and tokens (the inner Map pairs tokens and role associated)
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
// URL where our OpenVidu server is listening
private String OPENVIDU_URL;
// Secret shared with our OpenVidu server
private String SECRET;
public SessionController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
@ -45,51 +50,74 @@ public class SessionController {
}
System.out.println("Getting sessionId and token | {sessionName}={" + sessionName + "}");
// Role associated to this user
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
// Optional data to be passed to other users when this user connects to the video-call
// In this case, a JSON with the value we stored in the HttpSession object on login
String serverData = "{\"serverData\": \"" + httpSession.getAttribute("loggedUser") + "\"}";
// Build tokenOptions object with the serverData and the role
TokenOptions tokenOptions = new TokenOptions.Builder().data(serverData).role(role).build();
if (this.mapSessions.get(sessionName) != null) {
// Session already exists: return existing sessionId and a new token
System.out.println("Existing session " + sessionName);
try {
// Get the existing sessionId from our collection with
// the sessionName param ("TUTORIAL")
String sessionId = this.mapSessions.get(sessionName).getSessionId();
// Generate a new token with the recently created tokenOptions
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
// Update our collection storing the new token
this.mapSessionIdsTokens.get(sessionId).put(token, role);
// Add all the needed attributes to the template
model.addAttribute("sessionId", sessionId);
model.addAttribute("token", token);
model.addAttribute("nickName", clientData);
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
model.addAttribute("sessionName", sessionName);
// Return session.html template
return "session";
} catch (Exception e) {
// If error just return dashboard.html template
model.addAttribute("username", httpSession.getAttribute("loggedUser"));
return "dashboard";
}
} else {
// New session: return a new sessionId and token
// New session: return a new sessionId and a new token
System.out.println("New session " + sessionName);
try {
// Create a new OpenVidu Session
Session session = this.openVidu.createSession();
// Get the sessionId
String sessionId = session.getSessionId();
// Generate a new token with the recently created tokenOptions
String token = session.generateToken(tokenOptions);
// Store the session and the token in our collections
this.mapSessions.put(sessionName, session);
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
this.mapSessionIdsTokens.get(sessionId).put(token, role);
// Add all the needed attributes to the template
model.addAttribute("sessionId", sessionId);
model.addAttribute("token", token);
model.addAttribute("nickName", clientData);
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
model.addAttribute("sessionName", sessionName);
// Return session.html template
return "session";
} catch (Exception e) {
// If error just return dashboard.html template
model.addAttribute("username", httpSession.getAttribute("loggedUser"));
return "dashboard";
}
@ -107,29 +135,33 @@ public class SessionController {
}
System.out.println("Removing user | sessioName=" + sessionName + ", token=" + token);
// If the session exists
if (this.mapSessions.get(sessionName) != null) {
String sessionId = this.mapSessions.get(sessionName).getSessionId();
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
// If the token exists
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
// Last user left: session must be removed
this.mapSessions.remove(sessionName);
System.out.println(sessionName + " empty!");
}
model.addAttribute("sessionId", sessionId);
return "redirect:/dashboard";
} else {
// The TOKEN wasn't valid
System.out.println("Problems in the app server: the TOKEN wasn't valid");
return "redirect:/dashboard";
}
} else {
// The SESSIONID wasn't valid
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
return "redirect:/dashboard";
}
} else {
// The SESSION does not exist
System.out.println("Problems in the app server: the SESSION does not exist");
return "redirect:/dashboard";
}

View File

@ -44,10 +44,12 @@
<div id="img-div"><img src="images/openvidu_grey_bg_transp_cropped.png" /></div>
<form class="form-group jumbotron" action="/dashboard" method="post">
<p>
<label>User</label><input class="form-control" type="text" name="user" required="true"></input>
<label>User</label>
<input class="form-control" type="text" name="user" required="true"></input>
</p>
<p>
<label>Pass</label><input class="form-control" type="password" name="pass" required="true"></input>
<label>Pass</label>
<input class="form-control" type="password" name="pass" required="true"></input>
</p>
<p class="text-center">
<button class="btn btn-lg btn-info" type="submit">Log in</button>

View File

@ -136,7 +136,7 @@
};
initMainVideo(event.element, userData);
appendUserData(event.element, userData);
$(event.element).prop('muted', true);
$(event.element).prop('muted', true); // Mute local video
});

View File

@ -60,15 +60,17 @@ var users = [{
role: OpenViduRole.SUBSCRIBER
}];
// Environment variables
// Environment variable: URL where our OpenVidu server is listening
var OPENVIDU_URL = process.argv[2];
// Environment variable: secret shared with our OpenVidu server
var OPENVIDU_SECRET = process.argv[3];
// OpenVidu object
// OpenVidu object to ask openvidu-server for sessionId and token
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
// Objects for storing active sessions and users
// Collection to pair session names and OpenVidu Session objects
var mapSessionNameSession = {};
// Collection to pair sessionId's (identifiers of Session objects) and tokens
var mapSessionIdTokens = {};
/* CONFIGURATION */
@ -100,28 +102,36 @@ 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;
// Check if the user is already logged in
if (isLogged(req.session)) {
// User is already logged. Immediately return dashboard
user = req.session.loggedUser;
res.render('dashboard.ejs', {
user: user
});
} else {
// User wasn't logged and wants to
// Retrieve params from POST body
var user = req.body.user;
var pass = req.body.pass;
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
if (login(user, pass)) {
if (login(user, pass)) { // Correct user-pass
// Validate session and return OK
// Value stored in req.session allows us to identify the user in future requests
console.log("'" + user + "' has logged in");
req.session.loggedUser = user;
res.render('dashboard.ejs', {
user: user
});
} else {
req.session.loggedUser = user;
res.render('dashboard.ejs', {
user: user
});
} else { // Wrong user-pass
// Invalidate session and return index template
console.log("'" + user + "' invalid credentials");
req.session.destroy();
res.redirect('/');
}
}
req.session.destroy();
res.redirect('/');
}
}
}
app.post('/session', (req, res) => {
@ -129,23 +139,43 @@ app.post('/session', (req, res) => {
req.session.destroy();
res.redirect('/');
} else {
// The nickname sent by the client
var clientData = req.body.data;
// The video-call to connect ("TUTORIAL")
var sessionName = req.body.sessionname;
// Role associated to this user
var role = users.find(u => (u.user === req.session.loggedUser)).role;
// Optional data to be passed to other users when this user connects to the video-call
// In this case, a JSON with the value we stored in the req.session object on login
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
// Build tokenOptions object with the serverData and the role
var tokenOptions = new TokenOptions.Builder()
.data(serverData)
.role(role)
.build();
if (mapSessionNameSession[sessionName]) {
// Session already exists: return existing sessionId and a new token
console.log('Existing session ' + sessionName);
// Get the existing Session from the collection
var mySession = mapSessionNameSession[sessionName];
// Generate a new token asynchronously with the recently created tokenOptions
mySession.generateToken(tokenOptions, function (token) {
// Get the existing sessionId
var sessionId = mySession.getSessionId();
// Store the new token in the collection of tokens
mapSessionIdTokens[sessionId].push(token);
// Return session template with all the needed attributes
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.render('session.ejs', {
@ -156,15 +186,27 @@ app.post('/session', (req, res) => {
sessionName: sessionName
});
});
} else {
} else { // New session: return a new sessionId and a new token
console.log('New session ' + sessionName);
var mySession = OV.createSession();
mySession.getSessionId(function (sessionId) {
mapSessionNameSession[sessionName] = mySession;
mapSessionIdTokens[sessionId] = [];
// Create a new OpenVidu Session
var mySession = OV.createSession();
// Get the sessionId asynchronously
mySession.getSessionId(function (sessionId) {
// Store the new Session in the collection of Sessions
mapSessionNameSession[sessionName] = mySession;
// Store a new empty array in the collection of tokens
mapSessionIdTokens[sessionId] = [];
// Generate a new token asynchronously with the recently created tokenOptions
mySession.generateToken(tokenOptions, function (token) {
// Store the new token in the collection of tokens
mapSessionIdTokens[sessionId].push(token);
// Return session template with all the needed attributes
console.log('SESSIONID: ' + sessionId);
console.log('TOKEN: ' + token);
res.render('session.ejs', {
@ -185,16 +227,21 @@ app.post('/leave-session', (req, res) => {
req.session.destroy();
res.render('index.ejs');
} else {
// Retrieve params from POST body
var sessionName = req.body.sessionname;
var token = req.body.token;
console.log('Removing user | {sessionName, token}={' + sessionName + ', ' + token + '}');
// If the session exists
var mySession = mapSessionNameSession[sessionName];
if (mySession) {
var tokens = mapSessionIdTokens[mySession.getSessionId()];
if (tokens) {
var index = tokens.indexOf(token);
if (index !== -1) { // User left the session
// If the token exists
if (index !== -1) {
// Token removed!
tokens.splice(index, 1);
console.log(sessionName + ': ' + mapSessionIdTokens[mySession.getSessionId()].toString());
} else {
@ -202,7 +249,8 @@ app.post('/leave-session', (req, res) => {
console.log(msg);
res.redirect('/dashboard');
}
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) { // Last user left the session
if (mapSessionIdTokens[mySession.getSessionId()].length == 0) {
// Last user left: session must be removed
console.log(sessionName + ' empty!');
delete mapSessionNameSession[sessionName];
}

View File

@ -44,10 +44,12 @@
<div id="img-div"><img src="images/openvidu_grey_bg_transp_cropped.png" /></div>
<form class="form-group jumbotron" action="/dashboard" method="post">
<p>
<label>User</label><input class="form-control" type="text" name="user" required="true"></input>
<label>User</label>
<input class="form-control" type="text" name="user" required="true"></input>
</p>
<p>
<label>Pass</label><input class="form-control" type="password" name="pass" required="true"></input>
<label>Pass</label>
<input class="form-control" type="password" name="pass" required="true"></input>
</p>
<p class="text-center">
<button class="btn btn-lg btn-info" type="submit">Log in</button>

View File

@ -92,7 +92,7 @@
// When the HTML video has been appended to DOM...
subscriber.on('videoElementCreated', function (event) {
// Add a new HTML element for the user's name and nickname over its video
// Add a new HTML element for the user's name and nickname just below its video
appendUserData(event.element, subscriber.stream.connection);
});
});
@ -106,6 +106,7 @@
// --- 3) Connect to the session passing the retrieved token and some more data from
// the client (in this case a JSON with the nickname chosen by the user) ---
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
// If the connection is successful, initialize a publisher and publish to the session
@ -118,7 +119,7 @@
if (isPublisher()) {
// --- 4) Get your own camera stream ---
var publisher = OV.initPublisher('video-container', {
audio: true,
video: true,
@ -134,12 +135,12 @@
};
initMainVideo(event.element, userData);
appendUserData(event.element, userData);
$(event.element).prop('muted', true);
$(event.element).prop('muted', true); // Mute local video
});
// --- 5) Publish your stream ---
session.publish(publisher);
} else {